From f11107821e259d544dc42648f4cdba2b123cd71e Mon Sep 17 00:00:00 2001
From: Melanie Thielker
Date: Thu, 25 Sep 2008 17:26:32 +0000
Subject: Add an extension to allow registering multiple interfaces of a type
 with Scene. Make the script engines check that the engine name in the
 //Engine:language comment is a valid engine and treat it as a normal comment
 if it's not. //DotNetEngine: needs to be written as
 //ScriptEngine.DotNetEngine: now, since that is it's real internal name.
 //XEngine: still works

---
 OpenSim/Framework/IScene.cs                        |   1 +
 .../Region/Environment/Scenes/Scene.Inventory.cs   |   6 +
 OpenSim/Region/Environment/Scenes/Scene.cs         |  53 +++++++--
 OpenSim/Region/Environment/Scenes/SceneBase.cs     |   5 +
 OpenSim/Region/Interfaces/IScriptModule.cs         |  38 +++++++
 .../Common/ScriptEngineBase/EventManager.cs        |  15 ++-
 .../ScriptEngineBase/EventQueueThreadClass.cs      |   2 +-
 .../Common/ScriptEngineBase/ScriptEngine.cs        |   6 +-
 .../Shared/Api/Implementation/LSL_Api_Base.cs      |   2 +-
 .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 126 +++++++++++----------
 OpenSim/Region/ScriptEngine/XEngine/XEngine.cs     |  26 ++++-
 11 files changed, 199 insertions(+), 81 deletions(-)
 create mode 100644 OpenSim/Region/Interfaces/IScriptModule.cs

(limited to 'OpenSim')

diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index d3e79d0..b6043ac 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -65,5 +65,6 @@ namespace OpenSim.Framework
         string GetCapsPath(UUID agentId);
 
         T RequestModuleInterface<T>();
+        T[] RequestModuleInterfaces<T>();
     }
 }
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
index 2a9be81..8fec13f 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -178,6 +178,7 @@ namespace OpenSim.Region.Environment.Scenes
                                 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
                                 return UUID.Zero;
                             }
+                            remoteClient.SendAgentAlertMessage("Notecard saved", false);
                         }
                         else if ((InventoryType) item.InvType == InventoryType.LSL)
                         {
@@ -186,6 +187,7 @@ namespace OpenSim.Region.Environment.Scenes
                                 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
                                 return UUID.Zero;
                             }
+                            remoteClient.SendAgentAlertMessage("Script saved", false);
                         }
 
                         AssetBase asset =
@@ -287,6 +289,10 @@ namespace OpenSim.Region.Environment.Scenes
                 //
                 part.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine);
             }
+            else
+            {
+                remoteClient.SendAgentAlertMessage("Script saved", false);
+            }
         }
 
         /// <summary>
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 74502b8..e5f10b8 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -124,7 +124,7 @@ namespace OpenSim.Region.Environment.Scenes
         {
             get { return m_modules; }
         }
-        protected Dictionary<Type, object> ModuleInterfaces = new Dictionary<Type, object>();
+        protected Dictionary<Type, List<object> > ModuleInterfaces = new Dictionary<Type, List<object> >();
         protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>();
         protected Dictionary<string, ICommander> m_moduleCommanders = new Dictionary<string, ICommander>();
 
@@ -3025,10 +3025,27 @@ namespace OpenSim.Region.Environment.Scenes
         {
             if (!ModuleInterfaces.ContainsKey(typeof(M)))
             {
-                ModuleInterfaces.Add(typeof(M), mod);
+                List<Object> l = new List<Object>();
+                l.Add(mod);
+                ModuleInterfaces.Add(typeof(M), l);
             }
         }
 
+        public void StackModuleInterface<M>(M mod)
+        {
+            List<Object> l;
+            if (ModuleInterfaces.ContainsKey(typeof(M)))
+                l = ModuleInterfaces[typeof(M)];
+            else
+                l = new List<Object>();
+
+            if (l.Contains(mod))
+                return;
+
+            l.Add(mod);
+            ModuleInterfaces[typeof(M)] = l;
+        }
+
         /// <summary>
         /// For the given interface, retrieve the region module which implements it.
         /// </summary>
@@ -3037,7 +3054,7 @@ namespace OpenSim.Region.Environment.Scenes
         {
             if (ModuleInterfaces.ContainsKey(typeof(T)))
             {
-                return (T)ModuleInterfaces[typeof(T)];
+                return (T)ModuleInterfaces[typeof(T)][0];
             }
             else
             {
@@ -3045,6 +3062,22 @@ namespace OpenSim.Region.Environment.Scenes
             }
         }
 
+        public override T[] RequestModuleInterfaces<T>()
+        {
+            if (ModuleInterfaces.ContainsKey(typeof(T)))
+            {
+                List<T> ret = new List<T>();
+
+                foreach(Object o in ModuleInterfaces[typeof(T)])
+                    ret.Add((T)o);
+                return ret.ToArray();
+            }
+            else
+            {
+                return new T[] { default(T) };
+            }
+        }
+
         public void SetObjectCapacity(int objects)
         {
             if (m_statsReporter != null)
@@ -3628,7 +3661,7 @@ namespace OpenSim.Region.Environment.Scenes
             m_eventManager.TriggerNotAtTargetEvent(localID);
         }
 
-        private bool scriptDanger(SceneObjectPart part,Vector3 pos)
+        private bool ScriptDanger(SceneObjectPart part,Vector3 pos)
         {
             ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y);
             if (part != null)
@@ -3684,12 +3717,12 @@ namespace OpenSim.Region.Environment.Scenes
             }
         }
 
-        public bool scriptDanger(uint localID, Vector3 pos)
+        public bool ScriptDanger(uint localID, Vector3 pos)
         {
             SceneObjectPart part = GetSceneObjectPart(localID);
             if (part != null)
             {
-                return scriptDanger(part, pos);
+                return ScriptDanger(part, pos);
             }
             else
             {
@@ -3697,19 +3730,19 @@ namespace OpenSim.Region.Environment.Scenes
             }
         }
 
-        public bool pipeEventsForScript(uint localID)
+        public bool PipeEventsForScript(uint localID)
         {
             SceneObjectPart part = GetSceneObjectPart(localID);
             if (part != null)
             {
-                // Changed so that child prims of attachments return scriptDanger for their parent, so that
+                // Changed so that child prims of attachments return ScriptDanger for their parent, so that
                 //  their scripts will actually run.
                 //      -- Leaf, Tue Aug 12 14:17:05 EDT 2008
                 SceneObjectPart parent = part.ParentGroup.RootPart;
                 if (parent != null && parent.IsAttachment)
-                    return scriptDanger(parent, parent.GetWorldPosition());
+                    return ScriptDanger(parent, parent.GetWorldPosition());
                 else
-                    return scriptDanger(part, part.GetWorldPosition());
+                    return ScriptDanger(part, part.GetWorldPosition());
             }
             else
             {
diff --git a/OpenSim/Region/Environment/Scenes/SceneBase.cs b/OpenSim/Region/Environment/Scenes/SceneBase.cs
index 955fd22..1406b47 100644
--- a/OpenSim/Region/Environment/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneBase.cs
@@ -225,5 +225,10 @@ namespace OpenSim.Region.Environment.Scenes
         {
             return default(T);
         }
+
+        public virtual T[] RequestModuleInterfaces<T>()
+        {
+            return new T[] { default(T) };
+        }
     }
 }
diff --git a/OpenSim/Region/Interfaces/IScriptModule.cs b/OpenSim/Region/Interfaces/IScriptModule.cs
new file mode 100644
index 0000000..e01b472
--- /dev/null
+++ b/OpenSim/Region/Interfaces/IScriptModule.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSim Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Interfaces
+{
+    public interface IScriptModule
+    {
+        string ScriptEngineName { get; }
+    }
+}
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
index c8c9cd8..0308169 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
@@ -215,6 +215,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
 
         public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine)
         {
+            List<IScriptModule> engines = new List<IScriptModule>(myScriptEngine.World.RequestModuleInterfaces<IScriptModule>());
+
+            List<string> names = new List<string>();
+            foreach (IScriptModule m in engines)
+                names.Add(m.ScriptEngineName);
+
             int lineEnd = script.IndexOf('\n');
 
             if (lineEnd != 1)
@@ -224,8 +230,13 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
                 int colon = firstline.IndexOf(':');
                 if (firstline.Length > 2 && firstline.Substring(0, 2) == "//" && colon != -1)
                 {
-                    engine = firstline.Substring(2, colon-2);
-                    script = "//" + script.Substring(script.IndexOf(':')+1);
+                    string engineName = firstline.Substring(2, colon-2);
+
+                    if (names.Contains(engineName))
+                    {
+                        engine = engineName;
+                        script = "//" + script.Substring(script.IndexOf(':')+1);
+                    }
                 }
             }
 
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
index 1e71ae5..7f52793 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
@@ -282,7 +282,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
                                 //                                              QIS.functionName);
 #endif
                                 // Only pipe event if land supports it.
-                                if (m_ScriptEngine.World.pipeEventsForScript(QIS.localID))
+                                if (m_ScriptEngine.World.PipeEventsForScript(QIS.localID))
                                 {
                                     LastExecutionStarted = DateTime.Now.Ticks;
                                     KillCurrentScript = false;
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
index d423311..2bcd949 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
 using System.Reflection;
 using log4net;
 using Nini.Config;
+using OpenSim.Region.Interfaces;
 using OpenSim.Region.Environment.Interfaces;
 using OpenSim.Region.Environment.Scenes;
 using OpenSim.Region.ScriptEngine.Interfaces;
@@ -43,7 +44,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
     /// </summary>
     ///
     [Serializable]
-    public abstract class ScriptEngine : IRegionModule, ScriptServerInterfaces.ScriptEngine, iScriptEngineFunctionModule, IEventReceiver
+    public abstract class ScriptEngine : IRegionModule, IScriptModule, ScriptServerInterfaces.ScriptEngine, iScriptEngineFunctionModule, IEventReceiver
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -126,8 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
             m_log.Info("[" + ScriptEngineName + "]: Reading configuration from config section \"" + ScriptEngineName + "\"");
             ReadConfig();
 
-            // Should we iterate the region for scripts that needs starting?
-            // Or can we assume we are loaded before anything else so we can use proper events?
+            m_Scene.StackModuleInterface<IScriptModule>(this);
         }
 
         public void PostInitialise()
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api_Base.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api_Base.cs
index 320e878..396d924 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api_Base.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api_Base.cs
@@ -5114,7 +5114,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         public LSL_Integer llScriptDanger(LSL_Vector pos)
         {
             m_host.AddScriptLPS(1);
-            bool result = World.scriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z));
+            bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z));
             if (result)
             {
                 return 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 28a3b11..6e6d169 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -567,86 +567,90 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
                 }
                 else
                 {
-                    SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
-                        m_LocalID);
-    //                m_Engine.Log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
-    //                        m_PrimName, m_ScriptName, data.EventName, m_State);
-
-                    try
+                    if (m_Engine.World.PipeEventsForScript(m_LocalID) ||
+                        data.EventName == "control") // Don't freeze avies!
                     {
-                        m_CurrentEvent = data.EventName;
-                        m_EventStart = DateTime.Now;
-                        m_InEvent = true;
+                        SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
+                            m_LocalID);
+        //                m_Engine.Log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
+        //                        m_PrimName, m_ScriptName, data.EventName, m_State);
 
-                        m_Script.ExecuteEvent(State, data.EventName, data.Params);
+                        try
+                        {
+                            m_CurrentEvent = data.EventName;
+                            m_EventStart = DateTime.Now;
+                            m_InEvent = true;
 
-                        m_InEvent = false;
-                        m_CurrentEvent = String.Empty;
+                            m_Script.ExecuteEvent(State, data.EventName, data.Params);
 
-                        if (m_SaveState)
-                        {
-                            // This will be the very first event we deliver
-                            // (state_entry) in defualt state
-                            //
+                            m_InEvent = false;
+                            m_CurrentEvent = String.Empty;
 
-                            SaveState(m_Assembly);
+                            if (m_SaveState)
+                            {
+                                // This will be the very first event we deliver
+                                // (state_entry) in defualt state
+                                //
 
-                            m_SaveState = false;
-                        }
-                    }
-                    catch (Exception e)
-                    {
-                        m_InEvent = false;
-                        m_CurrentEvent = String.Empty;
+                                SaveState(m_Assembly);
 
-                        if (!(e is TargetInvocationException) || (!(e.InnerException is EventAbortException) && (!(e.InnerException is SelfDeleteException))))
+                                m_SaveState = false;
+                            }
+                        }
+                        catch (Exception e)
                         {
-                            if (e is System.Threading.ThreadAbortException)
+                            m_InEvent = false;
+                            m_CurrentEvent = String.Empty;
+
+                            if (!(e is TargetInvocationException) || (!(e.InnerException is EventAbortException) && (!(e.InnerException is SelfDeleteException))))
                             {
-                                lock (m_EventQueue)
+                                if (e is System.Threading.ThreadAbortException)
                                 {
-                                    if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
+                                    lock (m_EventQueue)
                                     {
-                                        m_CurrentResult=m_Engine.QueueEventHandler(this);
+                                        if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
+                                        {
+                                            m_CurrentResult=m_Engine.QueueEventHandler(this);
+                                        }
+                                        else
+                                        {
+                                            m_CurrentResult = null;
+                                        }
                                     }
-                                    else
-                                    {
-                                        m_CurrentResult = null;
-                                    }
-                                }
 
-                                m_DetectParams = null;
+                                    m_DetectParams = null;
 
-                                return 0;
-                            }
+                                    return 0;
+                                }
 
-                            try
-                            {
-                                // DISPLAY ERROR INWORLD
-                                string text = "Runtime error:\n" + e.InnerException.ToString();
-                                if (text.Length > 1000)
-                                    text = text.Substring(0, 1000);
-                                m_Engine.World.SimChat(Utils.StringToBytes(text),
-                                                       ChatTypeEnum.DebugChannel, 2147483647,
-                                                       part.AbsolutePosition,
-                                                       part.Name, part.UUID, false);
+                                try
+                                {
+                                    // DISPLAY ERROR INWORLD
+                                    string text = "Runtime error:\n" + e.InnerException.ToString();
+                                    if (text.Length > 1000)
+                                        text = text.Substring(0, 1000);
+                                    m_Engine.World.SimChat(Utils.StringToBytes(text),
+                                                           ChatTypeEnum.DebugChannel, 2147483647,
+                                                           part.AbsolutePosition,
+                                                           part.Name, part.UUID, false);
+                                }
+                                catch (Exception e2) // LEGIT: User Scripting
+                                {
+                                    m_Engine.Log.Error("[Script]: "+
+                                                       "Error displaying error in-world: " +
+                                                       e2.ToString());
+                                    m_Engine.Log.Error("[Script]: " +
+                                                       "Errormessage: Error compiling script:\r\n" +
+                                                       e.ToString());
+                                }
                             }
-                            catch (Exception e2) // LEGIT: User Scripting
+                            else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
                             {
-                                m_Engine.Log.Error("[Script]: "+
-                                                   "Error displaying error in-world: " +
-                                                   e2.ToString());
-                                m_Engine.Log.Error("[Script]: " +
-                                                   "Errormessage: Error compiling script:\r\n" +
-                                                   e.ToString());
+                                m_InSelfDelete = true;
+                                if (part != null && part.ParentGroup != null)
+                                    m_Engine.World.DeleteSceneObject(part.ParentGroup);
                             }
                         }
-                        else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
-                        {
-                            m_InSelfDelete = true;
-                            if (part != null && part.ParentGroup != null)
-                                m_Engine.World.DeleteSceneObject(part.ParentGroup);
-                        }
                     }
                 }
 
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 701ad60..f11ccc4 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -39,6 +39,7 @@ using log4net;
 using Nini.Config;
 using Amib.Threading;
 using OpenSim.Framework;
+using OpenSim.Region.Interfaces;
 using OpenSim.Region.Environment;
 using OpenSim.Region.Environment.Scenes;
 using OpenSim.Region.Environment.Interfaces;
@@ -50,7 +51,7 @@ using OpenSim.Region.ScriptEngine.Interfaces;
 
 namespace OpenSim.Region.ScriptEngine.XEngine
 {
-    public class XEngine : IRegionModule, IScriptEngine
+    public class XEngine : IRegionModule, IScriptModule, IScriptEngine
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
@@ -213,6 +214,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
             //
             SetupEngine(m_MinThreads, m_MaxThreads, m_IdleTimeout, m_Prio,
                         m_MaxScriptQueue, m_StackSize);
+
+            m_Scene.StackModuleInterface<IScriptModule>(this);
         }
 
         public void PostInitialise()
@@ -331,6 +334,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
 
         public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine)
         {
+            List<IScriptModule> engines = new List<IScriptModule>(m_Scene.RequestModuleInterfaces<IScriptModule>());
+
+            List<string> names = new List<string>();
+            foreach (IScriptModule m in engines)
+                names.Add(m.ScriptEngineName);
+
             int lineEnd = script.IndexOf('\n');
 
             if (lineEnd != 1)
@@ -340,8 +349,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
                 int colon = firstline.IndexOf(':');
                 if (firstline.Length > 2 && firstline.Substring(0, 2) == "//" && colon != -1)
                 {
-                    engine = firstline.Substring(2, colon-2);
-                    script = "//" + script.Substring(script.IndexOf(':')+1);
+                    string engineName = firstline.Substring(2, colon-2);
+
+                    if (names.Contains(engineName))
+                    {
+                        engine = engineName;
+                        script = "//" + script.Substring(script.IndexOf(':')+1);
+                    }
                 }
             }
 
@@ -454,14 +468,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
 //            m_log.DebugFormat("[XEngine] Compiling script {0} ({1})",
 //                    item.Name, itemID.ToString());
 
+            ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID);
+
             string assembly = "";
             try
             {
                 assembly = m_Compiler.PerformScriptCompile(script,
                                                            assetID.ToString());
+                if (presence != null)
+                    presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
             }
             catch (Exception e)
             {
+                if (presence != null)
+                    presence.ControllingClient.SendAgentAlertMessage("Script saved with errors, check debug window!", false);
                 try
                 {
                     // DISPLAY ERROR INWORLD
-- 
cgit v1.1