Browse Source

add cap AttachmentResources ( no urls, memory account is per yengine mem usage)

UbitUmarov 3 years ago
parent
commit
9aa7f41bca

+ 1 - 0
OpenSim/Framework/ILandObject.cs

@@ -194,5 +194,6 @@ namespace OpenSim.Framework
         string GetMusicUrl();
 
         void Clear();
+        ISceneObject[] GetSceneObjectGroups();
     }
 }

+ 68 - 0
OpenSim/Framework/SLUtil.cs

@@ -692,5 +692,73 @@ namespace OpenSim.Framework
                 return new string[0];
             return lines.ToArray();
         }
+
+        // libomv has old names on ATTACH_LEFT_PEC and ATTACH_RIGHT_PEC
+        public static readonly string[] AttachmentPointNames = new string[]
+        {
+            string.Empty,
+            "ATTACH_CHEST", // 1
+            "ATTACH_HEAD", // 2
+            "ATTACH_LSHOULDER", // 3
+            "ATTACH_RSHOULDER", // 4
+            "ATTACH_LHAND", // 5
+            "ATTACH_RHAND", // 6
+            "ATTACH_LFOOT", // 7
+            "ATTACH_RFOOT", // 8
+            "ATTACH_BACK", // 9
+            "ATTACH_PELVIS", // 10
+            "ATTACH_MOUTH", // 11
+            "ATTACH_CHIN", // 12
+            "ATTACH_LEAR", // 13
+            "ATTACH_REAR", // 14
+            "ATTACH_LEYE", // 15
+            "ATTACH_REYE", // 16
+            "ATTACH_NOSE", // 17
+            "ATTACH_RUARM", // 18
+            "ATTACH_RLARM", // 19
+            "ATTACH_LUARM", // 20
+            "ATTACH_LLARM", // 21
+            "ATTACH_RHIP", // 22
+            "ATTACH_RULEG", // 23
+            "ATTACH_RLLEG", // 24
+            "ATTACH_LHIP", // 25
+            "ATTACH_LULEG", // 26
+            "ATTACH_LLLEG", // 27
+            "ATTACH_BELLY", // 28
+            "ATTACH_LEFT_PEC", // 29
+            "ATTACH_RIGHT_PEC", // 30
+            "ATTACH_HUD_CENTER_2", // 31
+            "ATTACH_HUD_TOP_RIGHT", // 32
+            "ATTACH_HUD_TOP_CENTER", // 33
+            "ATTACH_HUD_TOP_LEFT", // 34
+            "ATTACH_HUD_CENTER_1", // 35
+            "ATTACH_HUD_BOTTOM_LEFT", // 36
+            "ATTACH_HUD_BOTTOM", // 37
+            "ATTACH_HUD_BOTTOM_RIGHT", // 38
+            "ATTACH_NECK", // 39
+            "ATTACH_AVATAR_CENTER", // 40
+            "ATTACH_LHAND_RING1", // 41
+            "ATTACH_RHAND_RING1", // 42
+            "ATTACH_TAIL_BASE", // 43
+            "ATTACH_TAIL_TIP", // 44
+            "ATTACH_LWING", // 45
+            "ATTACH_RWING", // 46
+            "ATTACH_FACE_JAW", // 47
+            "ATTACH_FACE_LEAR", // 48
+            "ATTACH_FACE_REAR", // 49
+            "ATTACH_FACE_LEYE", // 50
+            "ATTACH_FACE_REYE", // 51
+            "ATTACH_FACE_TONGUE", // 52
+            "ATTACH_GROIN", // 53
+            "ATTACH_HIND_LFOOT", // 54
+            "ATTACH_HIND_RFOOT" // 55
+        };
+
+        public static string GetAttachmentName(int point)
+        {
+            if(point < AttachmentPointNames.Length)
+                return AttachmentPointNames[point];
+            return "Unknown";
+        }
     }
 }

+ 222 - 3
OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs

@@ -122,7 +122,10 @@ namespace OpenSim.Region.ClientStack.Linden
 
         private bool m_AllowCapHomeLocation = true;
         private bool m_AllowCapGroupMemberData = true;
-        private  IUserManagement m_UserManager;
+        private bool m_AllowCapLandResources = true;
+        private bool m_AllowCapAttachmentResources = true;
+
+        private IUserManagement m_UserManager;
         private IUserAccountService m_userAccountService;
         private IMoneyModule m_moneyModule;
 
@@ -199,6 +202,14 @@ namespace OpenSim.Region.ClientStack.Linden
                     string GroupMemberDataUrl = CapsConfig.GetString("Cap_GroupMemberData", "localhost");
                     if(GroupMemberDataUrl == String.Empty)
                         m_AllowCapGroupMemberData = false;
+
+                    string LandResourcesUrl = CapsConfig.GetString("Cap_LandResources", "localhost");
+                    if (LandResourcesUrl == String.Empty)
+                        m_AllowCapLandResources = false;
+
+                    string AttachmentResourcesUrl = CapsConfig.GetString("Cap_AttachmentResources", "localhost");
+                    if (AttachmentResourcesUrl == String.Empty)
+                        m_AllowCapAttachmentResources = false;
                 }
             }
 
@@ -273,6 +284,17 @@ namespace OpenSim.Region.ClientStack.Linden
                         new SimpleStreamHandler(GetNewCapPath(), GroupMemberData));
                 }
 
+                if (m_AllowCapLandResources)
+                {
+                    m_HostCapsObj.RegisterSimpleHandler("LandResources",
+                        new SimpleOSDMapHandler("POST", GetNewCapPath(), LandResources));
+                }
+
+                if (m_AllowCapAttachmentResources)
+                {
+                    m_HostCapsObj.RegisterSimpleHandler("AttachmentResources",
+                        new SimpleStreamHandler(GetNewCapPath(), AttachmentResources));
+                }
             }
             catch (Exception e)
             {
@@ -1567,7 +1589,149 @@ namespace OpenSim.Region.ClientStack.Linden
             httpResponse.StatusCode = (int)HttpStatusCode.OK;
         }
 
-        public void ResourceCostSelected(IOSHttpRequest httpRequest,IOSHttpResponse httpResponse, OSDMap req)
+        public struct AttachmentScriptInfo
+        {
+            public byte attpoint;
+            public UUID id;
+            public string name;
+            public Vector3 pos;
+            public int memory;
+        };
+
+        public void AttachmentResources(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
+        {
+            if(m_Scene.TryGetScenePresence(m_AgentID, out ScenePresence sp) && !sp.IsChildAgent && !sp.IsDeleted && !sp.IsInTransit)
+            {
+                int totalmem = 0;
+                List<SceneObjectGroup> atts = sp.GetAttachments();
+                Dictionary<byte,List<AttachmentScriptInfo>> perAttPoints = new Dictionary<byte, List<AttachmentScriptInfo>>();
+                foreach(SceneObjectGroup so in atts)
+                {
+                    byte attp = so.GetAttachmentPoint();
+                    int mem = so.ScriptsMemory();
+                    totalmem += mem;
+                    AttachmentScriptInfo info = new AttachmentScriptInfo()
+                    {
+                        attpoint = attp,
+                        id = so.UUID,
+                        name = so.Name,
+                        memory = mem,
+                        pos = so.AbsolutePosition
+                    };
+                    if(perAttPoints.TryGetValue(attp, out List<AttachmentScriptInfo> la))
+                        la.Add(info);
+                    else
+                        perAttPoints[attp] = new List<AttachmentScriptInfo>(){  info };
+                }
+                StringBuilder sb = LLSDxmlEncode.Start();
+                LLSDxmlEncode.AddMap(sb);
+                LLSDxmlEncode.AddArray("attachments", sb);
+
+                foreach (KeyValuePair<byte, List<AttachmentScriptInfo>> kvp in perAttPoints)
+                {
+                    LLSDxmlEncode.AddMap(sb);
+                    LLSDxmlEncode.AddElem("location", SLUtil.GetAttachmentName(kvp.Key), sb);
+                    LLSDxmlEncode.AddArray("objects", sb);
+                    foreach(AttachmentScriptInfo asi in kvp.Value)
+                    {
+                        LLSDxmlEncode.AddMap(sb);
+                        LLSDxmlEncode.AddElem("id", asi.id, sb);
+                        LLSDxmlEncode.AddElem("is_group_owned", (int)0, sb);
+                        LLSDxmlEncode.AddElem("location", asi.pos, sb);
+                        LLSDxmlEncode.AddElem("name", asi.name, sb);
+                        LLSDxmlEncode.AddElem("owner_id", m_AgentID, sb);
+                        LLSDxmlEncode.AddMap("resources", sb);
+                        LLSDxmlEncode.AddElem("memory", asi.memory, sb);
+                        LLSDxmlEncode.AddEndMap(sb);
+                        LLSDxmlEncode.AddEndMap(sb);
+                    }
+                    LLSDxmlEncode.AddEndArray(sb);
+                    LLSDxmlEncode.AddEndMap(sb);
+                }
+                LLSDxmlEncode.AddEndArray(sb);
+
+                LLSDxmlEncode.AddMap("summary", sb);
+                LLSDxmlEncode.AddArray("available", sb);
+
+                LLSDxmlEncode.AddMap(sb);
+                LLSDxmlEncode.AddElem("amount", (int)38, sb);
+                LLSDxmlEncode.AddElem("type", "urls", sb);
+                LLSDxmlEncode.AddEndMap(sb);
+
+                LLSDxmlEncode.AddMap(sb);
+                LLSDxmlEncode.AddElem("amount", (int)-1, sb);
+                LLSDxmlEncode.AddElem("type", "memory", sb);
+                LLSDxmlEncode.AddEndMap(sb);
+                LLSDxmlEncode.AddEndArray(sb);
+
+                LLSDxmlEncode.AddArray("used", sb);
+
+                LLSDxmlEncode.AddMap(sb);
+                LLSDxmlEncode.AddElem("amount",(int) 0, sb);
+                LLSDxmlEncode.AddElem("type", "urls", sb);
+                LLSDxmlEncode.AddEndMap(sb);
+
+                LLSDxmlEncode.AddMap(sb);
+                LLSDxmlEncode.AddElem("amount", totalmem, sb);
+                LLSDxmlEncode.AddElem("type", "memory", sb);
+                LLSDxmlEncode.AddEndMap(sb);
+                LLSDxmlEncode.AddEndArray(sb);
+
+                LLSDxmlEncode.AddEndMap(sb);
+
+
+                LLSDxmlEncode.AddEndMap(sb);
+
+                string tst = sb.ToString();
+
+                httpResponse.RawBuffer = LLSDxmlEncode.EndToNBBytes(sb);
+                httpResponse.StatusCode = (int)HttpStatusCode.OK;
+                return;
+            }
+            httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
+        }
+
+        public void LandResources(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap req)
+        {
+            if(req.TryGetValue("parcel_id", out OSD tmp) && tmp is OSDUUID)
+            {
+                UUID parcelID = tmp.AsUUID();
+                if(!Util.ParseFakeParcelID(parcelID, out ulong regionHandle, out uint x, out uint y) || regionHandle != m_Scene.RegionInfo.RegionHandle)
+                {
+                    httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
+                    return;
+                }
+
+                ILandObject land = m_Scene.LandChannel.GetLandObject(x, y);
+                if(land == null || land.LandData == null)
+                {
+                    httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
+                    return;
+                }
+
+                string uploaderPath = GetNewCapPath();
+                ScriptResourceSummary uploader =
+                    new ScriptResourceSummary(land.LandData.LocalID, m_Scene, m_HostCapsObj.HttpListener, uploaderPath, httpRequest.RemoteIPEndPoint.Address);
+
+                m_HostCapsObj.RegisterSimpleHandler("LandResources",
+                                       new SimpleOSDMapHandler("POST", GetNewCapPath(), LandResources));
+
+                string protocol = m_HostCapsObj.SSLCaps ? "https://" : "http://";
+                string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath;
+
+                StringBuilder lsl = LLSDxmlEncode.Start();
+                LLSDxmlEncode.AddMap(lsl);
+                LLSDxmlEncode.AddElem("ScriptResourceSummary", uploaderURL,lsl);
+                LLSDxmlEncode.AddEndMap(lsl);
+
+                httpResponse.RawBuffer = LLSDxmlEncode.EndToNBBytes(lsl);
+                httpResponse.StatusCode = (int)HttpStatusCode.OK;
+                return;
+            }
+            httpResponse.StatusCode = (int)HttpStatusCode.BadRequest;
+        }
+
+        public void ResourceCostSelected(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap req)
         {
             float phys=0;
             float stream=0;
@@ -2192,4 +2356,59 @@ namespace OpenSim.Region.ClientStack.Linden
             fs.Close();
         }
     }
-}
+
+    public class ScriptResourceSummary
+    {
+        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private IHttpServer m_httpListener;
+        private string m_mypath;
+        private int m_parcelID;
+        private Scene m_scene;
+        private Timer m_timeoutTimer;
+
+        private IPAddress m_address;
+
+        public ScriptResourceSummary(int parcelID, Scene scene, IHttpServer httpServer, string path, IPAddress address)
+        {
+            m_httpListener = httpServer;
+            m_address = address;
+            m_mypath = path;
+            m_scene = scene;
+            m_parcelID = parcelID;
+
+            m_timeoutTimer = new Timer();
+            m_timeoutTimer.Elapsed += TimedOut;
+            m_timeoutTimer.Interval = 10000;
+            m_timeoutTimer.AutoReset = false;
+            m_timeoutTimer.Start();
+        }
+
+        /// <summary>
+        /// Handle raw asset upload data via the capability.
+        /// </summary>
+        /// <param name="data"></param>
+        /// <param name="path"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        public void ScriptResourceSummaryCap(IOSHttpRequest request, IOSHttpResponse response)
+        {
+            m_timeoutTimer.Stop();
+            m_httpListener.RemoveSimpleStreamHandler(m_mypath);
+            m_timeoutTimer.Dispose();
+
+            if (request.RemoteIPEndPoint.Address != m_address)
+            {
+                response.StatusCode = (int)HttpStatusCode.Unauthorized;
+                return;
+            }
+        }
+
+        private void TimedOut(object sender, ElapsedEventArgs args)
+        {
+            m_httpListener.RemoveSimpleStreamHandler(m_mypath);
+            m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out ScriptResourceSummary");
+            m_timeoutTimer.Dispose();
+        }
+    }
+}

+ 5 - 0
OpenSim/Region/CoreModules/World/Land/LandObject.cs

@@ -124,6 +124,11 @@ namespace OpenSim.Region.CoreModules.World.Land
             }
         }
 
+        public ISceneObject[] GetSceneObjectGroups()
+        {
+            return primsOverMe.ToArray();
+        }
+
         public Vector2? GetNearestPoint(Vector3 pos)
         {
             Vector3 direction = new Vector3(m_centerPoint.X - pos.X, m_centerPoint.Y - pos.Y, 0f );

+ 1 - 0
OpenSim/Region/Framework/Interfaces/IScriptModule.cs

@@ -109,6 +109,7 @@ namespace OpenSim.Region.Framework.Interfaces
         /// A float the value is a representative execution time in milliseconds of all scripts in that Array.
         /// </returns>
         float GetScriptExecutionTime(List<UUID> itemIDs);
+        int GetScriptsMemory(List<UUID> itemIDs);
 
         /// <summary>
         /// Get the execution times of all scripts in each object.

+ 36 - 0
OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs

@@ -5228,6 +5228,42 @@ namespace OpenSim.Region.Framework.Scenes
             return time;
         }
 
+        public int ScriptsMemory()
+        {
+            IScriptModule[] engines = Scene.RequestModuleInterfaces<IScriptModule>();
+
+            if (engines.Length == 0) // No engine at all
+                return 0;
+
+            int memory = 0;
+
+            // get all the scripts in all parts
+            SceneObjectPart[] parts = m_parts.GetArray();
+            List<TaskInventoryItem> scripts = new List<TaskInventoryItem>();
+            for (int i = 0; i < parts.Length; i++)
+            {
+                scripts.AddRange(parts[i].Inventory.GetInventoryItems(InventoryType.LSL));
+            }
+            // extract the UUIDs
+            List<UUID> ids = new List<UUID>(scripts.Count);
+            foreach (TaskInventoryItem script in scripts)
+            {
+                if (!ids.Contains(script.ItemID))
+                {
+                    ids.Add(script.ItemID);
+                }
+            }
+            // Offer the list of script UUIDs to each engine found and accumulate the memory
+            foreach (IScriptModule e in engines)
+            {
+                if (e != null)
+                {
+                    memory += e.GetScriptsMemory(ids);
+                }
+            }
+            return memory;
+        }
+
         /// <summary>
         /// Returns a count of the number of running scripts in this groups parts.
         /// </summary>

+ 5 - 0
OpenSim/Region/ScriptEngine/XEngine/XEngine.cs

@@ -2442,6 +2442,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
             return time;
         }
 
+        public int GetScriptsMemory(List<UUID> itemIDs)
+        {
+            return 0;
+        }
+
         private float GetExectionTime(IScriptInstance si)
         {
             return (float)si.ExecutionTime.GetSumTime().TotalMilliseconds;

+ 20 - 5
OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs

@@ -1915,11 +1915,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
         }
 
         /**
-         * @brief A float the value is a representative execution time in
-         *        milliseconds of all scripts in the link set.
-         * @param itemIDs = list of scripts in the link set
-         * @returns milliseconds for all those scripts
-         */
+            * @brief A float the value is a representative execution time in
+            *        milliseconds of all scripts in the link set.
+            * @param itemIDs = list of scripts in the link set
+            * @returns milliseconds for all those scripts
+            */
         public float GetScriptExecutionTime(List<UUID> itemIDs)
         {
             if((itemIDs == null) || (itemIDs.Count == 0))
@@ -1935,6 +1935,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
             return time;
         }
 
+        public int GetScriptsMemory(List<UUID> itemIDs)
+        {
+            if ((itemIDs == null) || (itemIDs.Count == 0))
+                return 0;
+
+            int memory = 0;
+            foreach (UUID itemID in itemIDs)
+            {
+                XMRInstance instance = GetInstance(itemID);
+                if ((instance != null) && instance.Running)
+                    memory += instance.xmrHeapUsed();
+            }
+            return memory;
+        }
+
         /**
          * @brief Block script from dequeuing events.
          */

+ 6 - 1
OpenSim/Tests/Common/Mock/MockScriptEngine.cs

@@ -198,7 +198,12 @@ namespace OpenSim.Tests.Common
 
         public float GetScriptExecutionTime(List<UUID> itemIDs)
         {
-            throw new System.NotImplementedException ();
+            return 0;
+        }
+
+        public int GetScriptsMemory(List<UUID> itemIDs)
+        {
+            return 0;
         }
 
         public Dictionary<uint, float> GetObjectScriptsExecutionTimes()

+ 1 - 1
bin/OpenSimDefaults.ini

@@ -765,7 +765,7 @@
     ;; set to localhost. These defaults can be overwritten
     ;; in OpenSim.ini
     ;;
-    Cap_AttachmentResources = ""
+    Cap_AttachmentResources = "localhost"
     Cap_ChatSessionRequest = ""
     Cap_CopyInventoryFromNotecard = "localhost"
     Cap_DispatchRegionInfo = ""