diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 0b6dd5e168..6f8ec43451 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -66,6 +66,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController throw new PluginNotInitialisedException (Name); } + public void Initialise(OpenSimBase openSim) { m_configSource = openSim.ConfigSource.Source; diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/ComponentLoader.cs b/OpenSim/ApplicationPlugins/ScriptEngine/ComponentLoader.cs deleted file mode 100644 index d2e3cd09ca..0000000000 --- a/OpenSim/ApplicationPlugins/ScriptEngine/ComponentLoader.cs +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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 System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Text; -using log4net; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; - -namespace OpenSim.ApplicationPlugins.ScriptEngine -{ - /// - /// Used to load ScriptEngine component .dll's - /// - internal class ComponentLoader - { - internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - //private ScriptEnginePlugin scriptEnginePlugin; - public ComponentLoader(ScriptEnginePlugin sep) - { - //scriptEnginePlugin = sep; - } - - /// - /// Load components from directory - /// - /// - public void Load(string directory) - { - // We may want to change how this functions as currently it required unique class names for each component - - foreach (string file in Directory.GetFiles(directory, "*.dll")) - { - //m_log.DebugFormat("[ScriptEngine]: Loading: [{0}].", file); - Assembly componentAssembly = Assembly.LoadFrom(file); - if (componentAssembly != null) - { - try - { - // Go through all types in the assembly - foreach (Type componentType in componentAssembly.GetTypes()) - { - if (componentType.IsPublic - && !componentType.IsAbstract) - { - if (componentType.IsSubclassOf(typeof (ComponentBase))) - { - // We have found an type which is derived from ProdiverBase, add it to provider list - m_log.InfoFormat("[ScriptEngine]: Adding component: {0}", componentType.Name); - lock (ComponentRegistry.providers) - { - ComponentRegistry.providers.Add(componentType.Name, componentType); - } - } - if (componentType.IsSubclassOf(typeof(RegionScriptEngineBase))) - { - // We have found an type which is derived from RegionScriptEngineBase, add it to engine list - m_log.InfoFormat("[ScriptEngine]: Adding script engine: {0}", componentType.Name); - lock (ComponentRegistry.scriptEngines) - { - ComponentRegistry.scriptEngines.Add(componentType.Name, componentType); - } - } - } - } - } - catch - (ReflectionTypeLoadException) - { - m_log.InfoFormat("[ScriptEngine]: Could not load types for [{0}].", componentAssembly.FullName); - } - } //if - } //foreach - } - } -} \ No newline at end of file diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/ComponentRegistry.cs b/OpenSim/ApplicationPlugins/ScriptEngine/ComponentRegistry.cs deleted file mode 100644 index 5ffa49031c..0000000000 --- a/OpenSim/ApplicationPlugins/ScriptEngine/ComponentRegistry.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 System.Collections.Generic; -using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; - -namespace OpenSim.ApplicationPlugins.ScriptEngine -{ - /// - /// Component providers - /// This is where any component (any part) of the Script Engine Component System (SECS) registers. - /// Nothing is instanciated at this point. The modules just need to register here to be available for any script engine. - /// - public static class ComponentRegistry - { - // Component providers are registered here wit a name (string) - // When a script engine is created the components are instanciated - public static Dictionary providers = new Dictionary(); - public static Dictionary scriptEngines = new Dictionary(); - - ///// - ///// Returns a list of ProviderBase objects which has been instanciated by their name - ///// - ///// List of Script Engine Components - ///// - //public static List GetComponents(string[] Providers) - //{ - // List pbl = new List(); - // if (Providers != null) - // { - // foreach (string p in Providers) - // { - // if (providers.ContainsKey(p)) - // pbl.Add(Activator.CreateInstance(providers[p]) as ComponentBase); - // } - // } - - // return pbl; - //} - - } -} \ No newline at end of file diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/RegionScriptEnginePlugin.cs b/OpenSim/ApplicationPlugins/ScriptEngine/RegionEngineLoader.cs similarity index 54% rename from OpenSim/ApplicationPlugins/ScriptEngine/RegionScriptEnginePlugin.cs rename to OpenSim/ApplicationPlugins/ScriptEngine/RegionEngineLoader.cs index e6def851a0..115d237aae 100644 --- a/OpenSim/ApplicationPlugins/ScriptEngine/RegionScriptEnginePlugin.cs +++ b/OpenSim/ApplicationPlugins/ScriptEngine/RegionEngineLoader.cs @@ -26,45 +26,51 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; +using log4net; using Nini.Config; using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Scenes; +using OpenSim.ScriptEngine.Shared; namespace OpenSim.ApplicationPlugins.ScriptEngine { - public class RegionScriptEnginePlugin : IRegionModule + public class RegionEngineLoader : IRegionModule { // This is a region module. // This means: Every time a new region is created, a new instance of this module is also created. // This module is responsible for starting the script engine for this region. + public string Name { get { return "SECS.DotNetEngine.Scheduler.RegionLoader"; } } + public bool IsSharedModule { get { return true; } } + internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private string tempScriptEngineName = "DotNetEngine"; - public RegionScriptEngineBase scriptEngine; + public IScriptEngine scriptEngine; + public IConfigSource ConfigSource; + public IConfig ScriptConfigSource; public void Initialise(Scene scene, IConfigSource source) { - return; // New region is being created // Create a new script engine -// try -// { -// lock (ComponentRegistry.scriptEngines) -// { -// scriptEngine = -// Activator.CreateInstance(ComponentRegistry.scriptEngines[tempScriptEngineName]) as -// RegionScriptEngineBase; -// } -// scriptEngine.Initialize(scene, source); -// } -// catch (Exception ex) -// { -// scriptEngine.m_log.Error("[ScriptEngine]: Unable to load engine \"" + tempScriptEngineName + "\": " + ex.ToString()); -// } + // Make sure we have config + if (ConfigSource.Configs["SECS"] == null) + ConfigSource.AddConfig("SECS"); + ScriptConfigSource = ConfigSource.Configs["SECS"]; + + // Is SECS enabled? + if (ScriptConfigSource.GetBoolean("Enabled", false)) + { + LoadEngine(); + if (scriptEngine != null) + scriptEngine.Initialise(scene, source); + } } public void PostInitialise() { - // Nothing + if (scriptEngine != null) + scriptEngine.PostInitialise(); } public void Close() @@ -76,18 +82,34 @@ namespace OpenSim.ApplicationPlugins.ScriptEngine } catch (Exception ex) { - scriptEngine.m_log.Error("[ScriptEngine]: Unable to close engine \"" + tempScriptEngineName + "\": " + ex.ToString()); + m_log.ErrorFormat("[{0}] Unable to close engine \"{1}\": {2}", Name, tempScriptEngineName, ex.ToString()); } } - public string Name + private void LoadEngine() { - get { return "ScriptEngine Region Loader"; } + m_log.DebugFormat("[{0}] Loading region script engine engine \"{1}\".", Name, tempScriptEngineName); + try + { + lock (ScriptEnginePlugin.scriptEngines) + { + if (!ScriptEnginePlugin.scriptEngines.ContainsKey(tempScriptEngineName)) + { + m_log.ErrorFormat("[{0}] Unable to load region script engine: Script engine \"{1}\" does not exist.", Name, tempScriptEngineName); + } + else + { + scriptEngine = + Activator.CreateInstance(ScriptEnginePlugin.scriptEngines[tempScriptEngineName]) as + IScriptEngine; + } + } + } + catch (Exception ex) + { + m_log.ErrorFormat("[{0}] Internal error loading region script engine \"{1}\": {2}", Name, tempScriptEngineName, ex.ToString()); + } } - public bool IsSharedModule - { - get { return true; } - } } } diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/RegionScriptEngineBase.cs b/OpenSim/ApplicationPlugins/ScriptEngine/RegionScriptEngineBase.cs deleted file mode 100644 index 89a90ae8ca..0000000000 --- a/OpenSim/ApplicationPlugins/ScriptEngine/RegionScriptEngineBase.cs +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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 System.Collections.Generic; -using System.Reflection; -using System.Text; -using log4net; -using Nini.Config; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; -using OpenSim.Region.Environment.Scenes; - -namespace OpenSim.ApplicationPlugins.ScriptEngine -{ - public abstract class RegionScriptEngineBase - { - - /// - /// Called on region initialize - /// - public abstract void Initialize(); - public abstract string Name { get; } - /// - /// Called before components receive Close() - /// - public abstract void PreClose(); - // Hold list of all the different components we have working for us - public List Components = new List(); - - public Scene m_Scene; - public IConfigSource m_ConfigSource; - public readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public void Initialize(Scene scene, IConfigSource source) - { - // Region started - m_Scene = scene; - m_ConfigSource = source; - Initialize(); - } - - /// - /// Creates instances of script engine components inside "components" List - /// - /// Array of comonent names to initialize - public void InitializeComponents(string[] ComponentList) - { - // Take list of providers to initialize and make instances of them - foreach (string c in ComponentList) - { - m_log.Info("[" + Name + "]: Loading: " + c); - lock (Components) - { - lock (ComponentRegistry.providers) - { - try - { - if (ComponentRegistry.providers.ContainsKey(c)) - Components.Add(Activator.CreateInstance(ComponentRegistry.providers[c]) as ComponentBase); - else - m_log.Error("[" + Name + "]: Component \"" + c + "\" not found, can not load"); - } - catch (Exception ex) - { - m_log.Error("[" + Name + "]: Exception loading \"" + c + "\": " + ex.ToString()); - } - } - } - } - - - // Run Initialize on all our providers, hand over a reference of ourself. - foreach (ComponentBase p in Components.ToArray()) - { - try - { - p.Initialize(this); - } - catch (Exception ex) - { - lock (Components) - { - m_log.Error("[" + Name + "]: Error initializing \"" + p.GetType().FullName + "\": " + - ex.ToString()); - if (Components.Contains(p)) - Components.Remove(p); - } - } - } - // All modules has been initialized, call Start() on them. - foreach (ComponentBase p in Components.ToArray()) - { - try - { - p.Start(); - } - catch (Exception ex) - { - lock (Components) - { - m_log.Error("[" + Name + "]: Error starting \"" + p.GetType().FullName + "\": " + ex.ToString()); - if (Components.Contains(p)) - Components.Remove(p); - } - } - } - - } - - #region Functions to return lists based on type - // Predicate for searching List for a certain type - private static bool FindType(ComponentBase pb) - { - if (pb.GetType() is T) - return true; - return false; - } - public List GetCommandComponentList() - { - return Components.FindAll(FindType); - } - public List GetCompilerComponentList() - { - return Components.FindAll(FindType); - } - public List GetEventComponentList() - { - return Components.FindAll(FindType); - } - public List GetScheduleComponentList() - { - return Components.FindAll(FindType); - } - - #endregion - - public void Close() - { - // We need to shut down - - // First call abstracted PreClose() - PreClose(); - - // Then Call Close() on all components - foreach (ComponentBase p in Components.ToArray()) - { - try - { - p.Close(); - } - catch (Exception) - { - // TODO: Print error to console - } - } - } - } -} - diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/Resources/ScriptEngine.addin.xml b/OpenSim/ApplicationPlugins/ScriptEngine/Resources/ScriptEngine.addin.xml deleted file mode 100644 index 38f6eb01a5..0000000000 --- a/OpenSim/ApplicationPlugins/ScriptEngine/Resources/ScriptEngine.addin.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/Resources/ScriptEnginePlugin.addin.xml b/OpenSim/ApplicationPlugins/ScriptEngine/Resources/ScriptEnginePlugin.addin.xml new file mode 100644 index 0000000000..f067bf4d39 --- /dev/null +++ b/OpenSim/ApplicationPlugins/ScriptEngine/Resources/ScriptEnginePlugin.addin.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs b/OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs index 32c7748b77..f81b848e35 100644 --- a/OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs +++ b/OpenSim/ApplicationPlugins/ScriptEngine/ScriptEnginePlugin.cs @@ -26,29 +26,143 @@ */ using System; using System.Collections.Generic; +using System.IO; using System.Reflection; using System.Text; +using System.Threading; +using OpenSim.ScriptEngine.Shared; using log4net; namespace OpenSim.ApplicationPlugins.ScriptEngine { + /// + /// Loads all Script Engine Components + /// public class ScriptEnginePlugin : IApplicationPlugin { internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); internal OpenSimBase m_OpenSim; - private ComponentLoader pluginLoader; + + // Component providers are registered here wit a name (string) + // When a script engine is created the components are instanciated + public static Dictionary providers = new Dictionary(); + public static Dictionary scriptEngines = new Dictionary(); + + + public ScriptEnginePlugin() + { + // Application startup +#if DEBUG + m_log.InfoFormat("[{0}] ##################################", Name); + m_log.InfoFormat("[{0}] # Script Engine Component System #", Name); + m_log.InfoFormat("[{0}] ##################################", Name); +#else + m_log.InfoFormat("[{0}] Script Engine Component System", Name); +#endif + + // Load all modules from current directory + // We only want files named OpenSim.ScriptEngine.*.dll + Load(".", "OpenSim.ScriptEngine.*.dll"); + } public void Initialise(OpenSimBase openSim) { + // Our objective: Load component .dll's m_OpenSim = openSim; - pluginLoader = new ComponentLoader(this); - - m_log.Info("[" + Name + "]: Script Engine Component System"); - m_log.Info("[" + Name + "]: Loading Script Engine Components"); - pluginLoader.Load("ScriptEngines"); - + //m_OpenSim.Shutdown(); } + + private readonly static string nameIScriptEngineComponent = typeof(IScriptEngineComponent).Name; // keep interface name in managed code + private readonly static string nameIScriptEngine = typeof(IScriptEngine).Name; // keep interface name in managed code + /// + /// Load components from directory + /// + /// + public void Load(string directory, string filter) + { + // We may want to change how this functions as currently it required unique class names for each component + + foreach (string file in Directory.GetFiles(directory, filter)) + { + //m_log.DebugFormat("[ScriptEngine]: Loading: [{0}].", file); + Assembly componentAssembly = null; + try + { + componentAssembly = Assembly.LoadFrom(file); + } catch (Exception e) + { + m_log.ErrorFormat("[{0}] Error loading: \"{1}\".", Name, file); + } + if (componentAssembly != null) + { + try + { + // Go through all types in the assembly + foreach (Type componentType in componentAssembly.GetTypes()) + { + if (componentType.IsPublic + && !componentType.IsAbstract) + { + //if (componentType.IsSubclassOf(typeof(ComponentBase))) + if (componentType.GetInterface(nameIScriptEngineComponent) != null) + { + // We have found an type which is derived from ProdiverBase, add it to provider list + m_log.InfoFormat("[{0}] Adding component: {1}", Name, componentType.Name); + lock (providers) + { + providers.Add(componentType.Name, componentType); + } + } + //if (componentType.IsSubclassOf(typeof(ScriptEngineBase))) + if (componentType.GetInterface(nameIScriptEngine) != null) + { + // We have found an type which is derived from RegionScriptEngineBase, add it to engine list + m_log.InfoFormat("[{0}] Adding script engine: {1}", Name, componentType.Name); + lock (scriptEngines) + { + scriptEngines.Add(componentType.Name, componentType); + } + } + } + } + } + catch + (ReflectionTypeLoadException re) + { + m_log.ErrorFormat("[{0}] Could not load component \"{1}\": {2}", Name, componentAssembly.FullName, re.ToString()); + int c = 0; + foreach (Exception e in re.LoaderExceptions) + { + c++; + m_log.ErrorFormat("[{0}] LoaderException {1}: {2}", Name, c, e.ToString()); + } + } + } //if + } //foreach + } + + public static IScriptEngineComponent GetComponentInstance(string name, params Object[] args) + { + if (!providers.ContainsKey(name)) + throw new Exception("ScriptEngine requested component named \"" + name + + "\" that does not exist."); + + return Activator.CreateInstance(providers[name], args) as IScriptEngineComponent; + } + + private readonly static string nameIScriptEngineRegionComponent = typeof(IScriptEngineRegionComponent).Name; // keep interface name in managed code + public static IScriptEngineComponent GetComponentInstance(RegionInfoStructure info, string name, params Object[] args) + { + IScriptEngineComponent c = GetComponentInstance(name, args); + + // If module is IScriptEngineRegionComponent then it will have one instance per region and we will initialize it + if (c.GetType().GetInterface(nameIScriptEngineRegionComponent) != null) + ((IScriptEngineRegionComponent)c).Initialize(info); + + return c; + } + #region IApplicationPlugin stuff /// /// Returns the plugin version @@ -65,16 +179,13 @@ namespace OpenSim.ApplicationPlugins.ScriptEngine /// Plugin name, eg MySQL User Provider public string Name { - get { return "ScriptEngine"; } + get { return "SECS"; } } /// /// Default-initialises the plugin /// - public void Initialise() - { - //throw new NotImplementedException(); - } + public void Initialise() { } /// ///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. @@ -85,5 +196,6 @@ namespace OpenSim.ApplicationPlugins.ScriptEngine //throw new NotImplementedException(); } #endregion + } } diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs index 17af2b05a0..30ba642ab3 100644 --- a/OpenSim/Data/SQLite/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs @@ -125,10 +125,10 @@ namespace OpenSim.Data.SQLite /// Asset Base override public void CreateAsset(AssetBase asset) { - m_log.Info("[ASSET DB]: Creating Asset " + Util.ToRawUuidString(asset.FullID)); + //m_log.Info("[ASSET DB]: Creating Asset " + Util.ToRawUuidString(asset.FullID)); if (ExistsAsset(asset.FullID)) { - m_log.Info("[ASSET DB]: Asset exists already, ignoring."); + //m_log.Info("[ASSET DB]: Asset exists already, ignoring."); } else { diff --git a/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs b/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs index cf601f1b34..6fe9fb4863 100644 --- a/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs +++ b/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs @@ -52,7 +52,7 @@ namespace OpenSim.Framework.AssetLoader.Filesystem if (!String.IsNullOrEmpty(path)) { - m_log.InfoFormat("[ASSETS]: Loading: [{0}][{1}]", name, path); + //m_log.InfoFormat("[ASSETS]: Loading: [{0}][{1}]", name, path); LoadAsset(asset, isImage, path); } @@ -131,7 +131,7 @@ namespace OpenSim.Framework.AssetLoader.Filesystem /// protected static void LoadXmlAssetSet(string assetSetPath, List assets) { - m_log.InfoFormat("[ASSETS]: Loading asset set {0}", assetSetPath); + //m_log.InfoFormat("[ASSETS]: Loading asset set {0}", assetSetPath); if (File.Exists(assetSetPath)) { diff --git a/OpenSim/Framework/PluginLoader.cs b/OpenSim/Framework/PluginLoader.cs index 497d9f52cc..440e0d5add 100644 --- a/OpenSim/Framework/PluginLoader.cs +++ b/OpenSim/Framework/PluginLoader.cs @@ -171,6 +171,7 @@ namespace OpenSim.Framework if (filters.ContainsKey (ext)) filter = filters [ext]; + List loadedPlugins = new List(); foreach (PluginExtensionNode node in AddinManager.GetExtensionNodes (ext)) { log.Info("[PLUGINS]: Trying plugin " + node.Path); @@ -179,8 +180,15 @@ namespace OpenSim.Framework continue; T plugin = (T) node.CreateInstance(); - Initialiser.Initialise (plugin); - Plugins.Add (plugin); + loadedPlugins.Add(plugin); + } + // We do Initialise() in a second loop after CreateInstance + // So that modules who need init before others can do it + // Example: Script Engine Component System needs to load its components before RegionLoader starts + foreach (T plugin in loadedPlugins) + { + Initialiser.Initialise(plugin); + Plugins.Add(plugin); } } } diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 69e80215ec..ebe4028dab 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -313,7 +313,6 @@ namespace OpenSim /// Execute the region creation process. This includes setting up scene infrastructure. /// /// - /// /// public IClientNetworkServer CreateRegion(RegionInfo regionInfo) { diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScript.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScript.cs index 3f494229fa..50be0e7a91 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScript.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScript.cs @@ -26,10 +26,8 @@ */ using System; -using System.Collections; using System.Collections.Generic; using OpenSim.Region.ScriptEngine.Interfaces; -using OpenSim.Region.ScriptEngine.Shared.ScriptBase; namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/Commands_LSL.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/Commands_LSL.cs index 703084cc2b..0b7c89487a 100644 --- a/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/Commands_LSL.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/Commands_LSL.cs @@ -28,18 +28,13 @@ using System; using System.Collections.Generic; using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; +using OpenSim.ScriptEngine.Shared; namespace OpenSim.ScriptEngine.Components.DotNetEngine.Commands_LSL { - public class Commands_LSL : CommandBase + public class Commands_LSL : IScriptEngineComponent { - public override void Start() - { - } - public override void Close() - { - } + } } diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/LSL_BaseClass.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/LSL_BaseClass.cs new file mode 100644 index 0000000000..173b2599e7 --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/LSL_BaseClass.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using log4net; +using OpenSim.ScriptEngine.Shared; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Commands_LSL +{ + public class Script : IScriptCommandProvider + { + internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public void llSay(int channelID, string text) + { + m_log.InfoFormat("[{0}] llSay({1}, \"{2}\")", "(Commands_LSL)OpenSim.ScriptEngine.Components.DotNetEngine.Commands_LSL.Script", channelID, text); + } + + public void ExecuteCommand(string functionName, params object[] args) + { + + } + + public string Name + { + get { return "SECS.DotNetEngine.Commands_LSL.Script"; } + } + } +} \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/LSL_Constants.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/LSL_Constants.cs new file mode 100644 index 0000000000..9dd3c2f876 --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_LSL/LSL_Constants.cs @@ -0,0 +1,498 @@ +/* + * 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 vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Commands_LSL +{ + public class LSL_Constants : MarshalByRefObject + { + // LSL CONSTANTS + public static readonly LSLInteger TRUE = new LSLInteger(1); + public static readonly LSLInteger FALSE = new LSLInteger(0); + + public const int STATUS_PHYSICS = 1; + public const int STATUS_ROTATE_X = 2; + public const int STATUS_ROTATE_Y = 4; + public const int STATUS_ROTATE_Z = 8; + public const int STATUS_PHANTOM = 16; + public const int STATUS_SANDBOX = 32; + public const int STATUS_BLOCK_GRAB = 64; + public const int STATUS_DIE_AT_EDGE = 128; + public const int STATUS_RETURN_AT_EDGE = 256; + public const int STATUS_CAST_SHADOWS = 512; + + public const int AGENT = 1; + public const int ACTIVE = 2; + public const int PASSIVE = 4; + public const int SCRIPTED = 8; + + public const int CONTROL_FWD = 1; + public const int CONTROL_BACK = 2; + public const int CONTROL_LEFT = 4; + public const int CONTROL_RIGHT = 8; + public const int CONTROL_UP = 16; + public const int CONTROL_DOWN = 32; + public const int CONTROL_ROT_LEFT = 256; + public const int CONTROL_ROT_RIGHT = 512; + public const int CONTROL_LBUTTON = 268435456; + public const int CONTROL_ML_LBUTTON = 1073741824; + + //Permissions + public const int PERMISSION_DEBIT = 2; + public const int PERMISSION_TAKE_CONTROLS = 4; + public const int PERMISSION_REMAP_CONTROLS = 8; + public const int PERMISSION_TRIGGER_ANIMATION = 16; + public const int PERMISSION_ATTACH = 32; + public const int PERMISSION_RELEASE_OWNERSHIP = 64; + public const int PERMISSION_CHANGE_LINKS = 128; + public const int PERMISSION_CHANGE_JOINTS = 256; + public const int PERMISSION_CHANGE_PERMISSIONS = 512; + public const int PERMISSION_TRACK_CAMERA = 1024; + public const int PERMISSION_CONTROL_CAMERA = 2048; + + public const int AGENT_FLYING = 1; + public const int AGENT_ATTACHMENTS = 2; + public const int AGENT_SCRIPTED = 4; + public const int AGENT_MOUSELOOK = 8; + public const int AGENT_SITTING = 16; + public const int AGENT_ON_OBJECT = 32; + public const int AGENT_AWAY = 64; + public const int AGENT_WALKING = 128; + public const int AGENT_IN_AIR = 256; + public const int AGENT_TYPING = 512; + public const int AGENT_CROUCHING = 1024; + public const int AGENT_BUSY = 2048; + public const int AGENT_ALWAYS_RUN = 4096; + + //Particle Systems + public const int PSYS_PART_INTERP_COLOR_MASK = 1; + public const int PSYS_PART_INTERP_SCALE_MASK = 2; + public const int PSYS_PART_BOUNCE_MASK = 4; + public const int PSYS_PART_WIND_MASK = 8; + public const int PSYS_PART_FOLLOW_SRC_MASK = 16; + public const int PSYS_PART_FOLLOW_VELOCITY_MASK = 32; + public const int PSYS_PART_TARGET_POS_MASK = 64; + public const int PSYS_PART_TARGET_LINEAR_MASK = 128; + public const int PSYS_PART_EMISSIVE_MASK = 256; + public const int PSYS_PART_FLAGS = 0; + public const int PSYS_PART_START_COLOR = 1; + public const int PSYS_PART_START_ALPHA = 2; + public const int PSYS_PART_END_COLOR = 3; + public const int PSYS_PART_END_ALPHA = 4; + public const int PSYS_PART_START_SCALE = 5; + public const int PSYS_PART_END_SCALE = 6; + public const int PSYS_PART_MAX_AGE = 7; + public const int PSYS_SRC_ACCEL = 8; + public const int PSYS_SRC_PATTERN = 9; + public const int PSYS_SRC_INNERANGLE = 10; + public const int PSYS_SRC_OUTERANGLE = 11; + public const int PSYS_SRC_TEXTURE = 12; + public const int PSYS_SRC_BURST_RATE = 13; + public const int PSYS_SRC_BURST_PART_COUNT = 15; + public const int PSYS_SRC_BURST_RADIUS = 16; + public const int PSYS_SRC_BURST_SPEED_MIN = 17; + public const int PSYS_SRC_BURST_SPEED_MAX = 18; + public const int PSYS_SRC_MAX_AGE = 19; + public const int PSYS_SRC_TARGET_KEY = 20; + public const int PSYS_SRC_OMEGA = 21; + public const int PSYS_SRC_ANGLE_BEGIN = 22; + public const int PSYS_SRC_ANGLE_END = 23; + public const int PSYS_SRC_PATTERN_DROP = 1; + public const int PSYS_SRC_PATTERN_EXPLODE = 2; + public const int PSYS_SRC_PATTERN_ANGLE = 4; + public const int PSYS_SRC_PATTERN_ANGLE_CONE = 8; + public const int PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY = 16; + + public const int VEHICLE_TYPE_NONE = 0; + public const int VEHICLE_TYPE_SLED = 1; + public const int VEHICLE_TYPE_CAR = 2; + public const int VEHICLE_TYPE_BOAT = 3; + public const int VEHICLE_TYPE_AIRPLANE = 4; + public const int VEHICLE_TYPE_BALLOON = 5; + public const int VEHICLE_LINEAR_FRICTION_TIMESCALE = 16; + public const int VEHICLE_ANGULAR_FRICTION_TIMESCALE = 17; + public const int VEHICLE_LINEAR_MOTOR_DIRECTION = 18; + public const int VEHICLE_LINEAR_MOTOR_OFFSET = 20; + public const int VEHICLE_ANGULAR_MOTOR_DIRECTION = 19; + public const int VEHICLE_HOVER_HEIGHT = 24; + public const int VEHICLE_HOVER_EFFICIENCY = 25; + public const int VEHICLE_HOVER_TIMESCALE = 26; + public const int VEHICLE_BUOYANCY = 27; + public const int VEHICLE_LINEAR_DEFLECTION_EFFICIENCY = 28; + public const int VEHICLE_LINEAR_DEFLECTION_TIMESCALE = 29; + public const int VEHICLE_LINEAR_MOTOR_TIMESCALE = 30; + public const int VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE = 31; + public const int VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY = 32; + public const int VEHICLE_ANGULAR_DEFLECTION_TIMESCALE = 33; + public const int VEHICLE_ANGULAR_MOTOR_TIMESCALE = 34; + public const int VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE = 35; + public const int VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY = 36; + public const int VEHICLE_VERTICAL_ATTRACTION_TIMESCALE = 37; + public const int VEHICLE_BANKING_EFFICIENCY = 38; + public const int VEHICLE_BANKING_MIX = 39; + public const int VEHICLE_BANKING_TIMESCALE = 40; + public const int VEHICLE_REFERENCE_FRAME = 44; + public const int VEHICLE_FLAG_NO_DEFLECTION_UP = 1; + public const int VEHICLE_FLAG_LIMIT_ROLL_ONLY = 2; + public const int VEHICLE_FLAG_HOVER_WATER_ONLY = 4; + public const int VEHICLE_FLAG_HOVER_TERRAIN_ONLY = 8; + public const int VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT = 16; + public const int VEHICLE_FLAG_HOVER_UP_ONLY = 32; + public const int VEHICLE_FLAG_LIMIT_MOTOR_UP = 64; + public const int VEHICLE_FLAG_MOUSELOOK_STEER = 128; + public const int VEHICLE_FLAG_MOUSELOOK_BANK = 256; + public const int VEHICLE_FLAG_CAMERA_DECOUPLED = 512; + + public const int INVENTORY_ALL = -1; + public const int INVENTORY_NONE = -1; + public const int INVENTORY_TEXTURE = 0; + public const int INVENTORY_SOUND = 1; + public const int INVENTORY_LANDMARK = 3; + public const int INVENTORY_CLOTHING = 5; + public const int INVENTORY_OBJECT = 6; + public const int INVENTORY_NOTECARD = 7; + public const int INVENTORY_SCRIPT = 10; + public const int INVENTORY_BODYPART = 13; + public const int INVENTORY_ANIMATION = 20; + public const int INVENTORY_GESTURE = 21; + + public const int ATTACH_CHEST = 1; + public const int ATTACH_HEAD = 2; + public const int ATTACH_LSHOULDER = 3; + public const int ATTACH_RSHOULDER = 4; + public const int ATTACH_LHAND = 5; + public const int ATTACH_RHAND = 6; + public const int ATTACH_LFOOT = 7; + public const int ATTACH_RFOOT = 8; + public const int ATTACH_BACK = 9; + public const int ATTACH_PELVIS = 10; + public const int ATTACH_MOUTH = 11; + public const int ATTACH_CHIN = 12; + public const int ATTACH_LEAR = 13; + public const int ATTACH_REAR = 14; + public const int ATTACH_LEYE = 15; + public const int ATTACH_REYE = 16; + public const int ATTACH_NOSE = 17; + public const int ATTACH_RUARM = 18; + public const int ATTACH_RLARM = 19; + public const int ATTACH_LUARM = 20; + public const int ATTACH_LLARM = 21; + public const int ATTACH_RHIP = 22; + public const int ATTACH_RULEG = 23; + public const int ATTACH_RLLEG = 24; + public const int ATTACH_LHIP = 25; + public const int ATTACH_LULEG = 26; + public const int ATTACH_LLLEG = 27; + public const int ATTACH_BELLY = 28; + public const int ATTACH_RPEC = 29; + public const int ATTACH_LPEC = 30; + + public const int LAND_LEVEL = 0; + public const int LAND_RAISE = 1; + public const int LAND_LOWER = 2; + public const int LAND_SMOOTH = 3; + public const int LAND_NOISE = 4; + public const int LAND_REVERT = 5; + public const int LAND_SMALL_BRUSH = 1; + public const int LAND_MEDIUM_BRUSH = 2; + public const int LAND_LARGE_BRUSH = 3; + + //Agent Dataserver + public const int DATA_ONLINE = 1; + public const int DATA_NAME = 2; + public const int DATA_BORN = 3; + public const int DATA_RATING = 4; + public const int DATA_SIM_POS = 5; + public const int DATA_SIM_STATUS = 6; + public const int DATA_SIM_RATING = 7; + public const int DATA_PAYINFO = 8; + public const int DATA_SIM_RELEASE = 128; + + public const int ANIM_ON = 1; + public const int LOOP = 2; + public const int REVERSE = 4; + public const int PING_PONG = 8; + public const int SMOOTH = 16; + public const int ROTATE = 32; + public const int SCALE = 64; + public const int ALL_SIDES = -1; + public const int LINK_SET = -1; + public const int LINK_ROOT = 1; + public const int LINK_ALL_OTHERS = -2; + public const int LINK_ALL_CHILDREN = -3; + public const int LINK_THIS = -4; + public const int CHANGED_INVENTORY = 1; + public const int CHANGED_COLOR = 2; + public const int CHANGED_SHAPE = 4; + public const int CHANGED_SCALE = 8; + public const int CHANGED_TEXTURE = 16; + public const int CHANGED_LINK = 32; + public const int CHANGED_ALLOWED_DROP = 64; + public const int CHANGED_OWNER = 128; + public const int CHANGED_REGION_RESTART = 256; + public const int CHANGED_REGION = 512; + public const int CHANGED_TELEPORT = 1024; + public const int TYPE_INVALID = 0; + public const int TYPE_INTEGER = 1; + public const int TYPE_FLOAT = 2; + public const int TYPE_STRING = 3; + public const int TYPE_KEY = 4; + public const int TYPE_VECTOR = 5; + public const int TYPE_ROTATION = 6; + + //XML RPC Remote Data Channel + public const int REMOTE_DATA_CHANNEL = 1; + public const int REMOTE_DATA_REQUEST = 2; + public const int REMOTE_DATA_REPLY = 3; + + //llHTTPRequest + public const int HTTP_METHOD = 0; + public const int HTTP_MIMETYPE = 1; + public const int HTTP_BODY_MAXLENGTH = 2; + public const int HTTP_VERIFY_CERT = 3; + + public const int PRIM_MATERIAL = 2; + public const int PRIM_PHYSICS = 3; + public const int PRIM_TEMP_ON_REZ = 4; + public const int PRIM_PHANTOM = 5; + public const int PRIM_POSITION = 6; + public const int PRIM_SIZE = 7; + public const int PRIM_ROTATION = 8; + public const int PRIM_TYPE = 9; + public const int PRIM_TEXTURE = 17; + public const int PRIM_COLOR = 18; + public const int PRIM_BUMP_SHINY = 19; + public const int PRIM_FULLBRIGHT = 20; + public const int PRIM_FLEXIBLE = 21; + public const int PRIM_TEXGEN = 22; + public const int PRIM_CAST_SHADOWS = 24; // Not implemented, here for completeness sake + public const int PRIM_POINT_LIGHT = 23; // Huh? + public const int PRIM_GLOW = 25; + public const int PRIM_TEXGEN_DEFAULT = 0; + public const int PRIM_TEXGEN_PLANAR = 1; + + public const int PRIM_TYPE_BOX = 0; + public const int PRIM_TYPE_CYLINDER = 1; + public const int PRIM_TYPE_PRISM = 2; + public const int PRIM_TYPE_SPHERE = 3; + public const int PRIM_TYPE_TORUS = 4; + public const int PRIM_TYPE_TUBE = 5; + public const int PRIM_TYPE_RING = 6; + public const int PRIM_TYPE_SCULPT = 7; + + public const int PRIM_HOLE_DEFAULT = 0; + public const int PRIM_HOLE_CIRCLE = 16; + public const int PRIM_HOLE_SQUARE = 32; + public const int PRIM_HOLE_TRIANGLE = 48; + + public const int PRIM_MATERIAL_STONE = 0; + public const int PRIM_MATERIAL_METAL = 1; + public const int PRIM_MATERIAL_GLASS = 2; + public const int PRIM_MATERIAL_WOOD = 3; + public const int PRIM_MATERIAL_FLESH = 4; + public const int PRIM_MATERIAL_PLASTIC = 5; + public const int PRIM_MATERIAL_RUBBER = 6; + public const int PRIM_MATERIAL_LIGHT = 7; + + public const int PRIM_SHINY_NONE = 0; + public const int PRIM_SHINY_LOW = 1; + public const int PRIM_SHINY_MEDIUM = 2; + public const int PRIM_SHINY_HIGH = 3; + public const int PRIM_BUMP_NONE = 0; + public const int PRIM_BUMP_BRIGHT = 1; + public const int PRIM_BUMP_DARK = 2; + public const int PRIM_BUMP_WOOD = 3; + public const int PRIM_BUMP_BARK = 4; + public const int PRIM_BUMP_BRICKS = 5; + public const int PRIM_BUMP_CHECKER = 6; + public const int PRIM_BUMP_CONCRETE = 7; + public const int PRIM_BUMP_TILE = 8; + public const int PRIM_BUMP_STONE = 9; + public const int PRIM_BUMP_DISKS = 10; + public const int PRIM_BUMP_GRAVEL = 11; + public const int PRIM_BUMP_BLOBS = 12; + public const int PRIM_BUMP_SIDING = 13; + public const int PRIM_BUMP_LARGETILE = 14; + public const int PRIM_BUMP_STUCCO = 15; + public const int PRIM_BUMP_SUCTION = 16; + public const int PRIM_BUMP_WEAVE = 17; + + public const int PRIM_SCULPT_TYPE_SPHERE = 1; + public const int PRIM_SCULPT_TYPE_TORUS = 2; + public const int PRIM_SCULPT_TYPE_PLANE = 3; + public const int PRIM_SCULPT_TYPE_CYLINDER = 4; + + public const int MASK_BASE = 0; + public const int MASK_OWNER = 1; + public const int MASK_GROUP = 2; + public const int MASK_EVERYONE = 3; + public const int MASK_NEXT = 4; + + public const int PERM_TRANSFER = 8192; + public const int PERM_MODIFY = 16384; + public const int PERM_COPY = 32768; + public const int PERM_MOVE = 524288; + public const int PERM_ALL = 2147483647; + + public const int PARCEL_MEDIA_COMMAND_STOP = 0; + public const int PARCEL_MEDIA_COMMAND_PAUSE = 1; + public const int PARCEL_MEDIA_COMMAND_PLAY = 2; + public const int PARCEL_MEDIA_COMMAND_LOOP = 3; + public const int PARCEL_MEDIA_COMMAND_TEXTURE = 4; + public const int PARCEL_MEDIA_COMMAND_URL = 5; + public const int PARCEL_MEDIA_COMMAND_TIME = 6; + public const int PARCEL_MEDIA_COMMAND_AGENT = 7; + public const int PARCEL_MEDIA_COMMAND_UNLOAD = 8; + public const int PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9; + public const int PARCEL_MEDIA_COMMAND_TYPE = 10; + public const int PARCEL_MEDIA_COMMAND_SIZE = 11; + public const int PARCEL_MEDIA_COMMAND_DESC = 12; + + public const int PARCEL_FLAG_ALLOW_FLY = 0x1; // parcel allows flying + public const int PARCEL_FLAG_ALLOW_SCRIPTS = 0x2; // parcel allows outside scripts + public const int PARCEL_FLAG_ALLOW_LANDMARK = 0x8; // parcel allows landmarks to be created + public const int PARCEL_FLAG_ALLOW_TERRAFORM = 0x10; // parcel allows anyone to terraform the land + public const int PARCEL_FLAG_ALLOW_DAMAGE = 0x20; // parcel allows damage + public const int PARCEL_FLAG_ALLOW_CREATE_OBJECTS = 0x40; // parcel allows anyone to create objects + public const int PARCEL_FLAG_USE_ACCESS_GROUP = 0x100; // parcel limits access to a group + public const int PARCEL_FLAG_USE_ACCESS_LIST = 0x200; // parcel limits access to a list of residents + public const int PARCEL_FLAG_USE_BAN_LIST = 0x400; // parcel uses a ban list, including restricting access based on payment info + public const int PARCEL_FLAG_USE_LAND_PASS_LIST = 0x800; // parcel allows passes to be purchased + public const int PARCEL_FLAG_LOCAL_SOUND_ONLY = 0x8000; // parcel restricts spatialized sound to the parcel + public const int PARCEL_FLAG_RESTRICT_PUSHOBJECT = 0x200000; // parcel restricts llPushObject + public const int PARCEL_FLAG_ALLOW_GROUP_SCRIPTS = 0x2000000; // parcel allows scripts owned by group + public const int PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS = 0x4000000; // parcel allows group object creation + public const int PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY = 0x8000000; // parcel allows objects owned by any user to enter + public const int PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY = 0x10000000; // parcel allows with the same group to enter + + public const int REGION_FLAG_ALLOW_DAMAGE = 0x1; // region is entirely damage enabled + public const int REGION_FLAG_FIXED_SUN = 0x10; // region has a fixed sun position + public const int REGION_FLAG_BLOCK_TERRAFORM = 0x40; // region terraforming disabled + public const int REGION_FLAG_SANDBOX = 0x100; // region is a sandbox + public const int REGION_FLAG_DISABLE_COLLISIONS = 0x1000; // region has disabled collisions + public const int REGION_FLAG_DISABLE_PHYSICS = 0x4000; // region has disabled physics + public const int REGION_FLAG_BLOCK_FLY = 0x80000; // region blocks flying + public const int REGION_FLAG_ALLOW_DIRECT_TELEPORT = 0x100000; // region allows direct teleports + public const int REGION_FLAG_RESTRICT_PUSHOBJECT = 0x400000; // region restricts llPushObject + + public const int PAY_HIDE = -1; + public const int PAY_DEFAULT = -2; + + public const string NULL_KEY = "00000000-0000-0000-0000-000000000000"; + public const string EOF = "\n\n\n"; + public const double PI = 3.14159274f; + public const double TWO_PI = 6.28318548f; + public const double PI_BY_TWO = 1.57079637f; + public const double DEG_TO_RAD = 0.01745329238f; + public const double RAD_TO_DEG = 57.29578f; + public const double SQRT2 = 1.414213538f; + public const int STRING_TRIM_HEAD = 1; + public const int STRING_TRIM_TAIL = 2; + public const int STRING_TRIM = 3; + public const int LIST_STAT_RANGE = 0; + public const int LIST_STAT_MIN = 1; + public const int LIST_STAT_MAX = 2; + public const int LIST_STAT_MEAN = 3; + public const int LIST_STAT_MEDIAN = 4; + public const int LIST_STAT_STD_DEV = 5; + public const int LIST_STAT_SUM = 6; + public const int LIST_STAT_SUM_SQUARES = 7; + public const int LIST_STAT_NUM_COUNT = 8; + public const int LIST_STAT_GEOMETRIC_MEAN = 9; + public const int LIST_STAT_HARMONIC_MEAN = 100; + + //ParcelPrim Categories + public const int PARCEL_COUNT_TOTAL = 0; + public const int PARCEL_COUNT_OWNER = 1; + public const int PARCEL_COUNT_GROUP = 2; + public const int PARCEL_COUNT_OTHER = 3; + public const int PARCEL_COUNT_SELECTED = 4; + public const int PARCEL_COUNT_TEMP = 5; + + public const int DEBUG_CHANNEL = 0x7FFFFFFF; + public const int PUBLIC_CHANNEL = 0x00000000; + + public const int OBJECT_NAME = 1; + public const int OBJECT_DESC = 2; + public const int OBJECT_POS = 3; + public const int OBJECT_ROT = 4; + public const int OBJECT_VELOCITY = 5; + public const int OBJECT_OWNER = 6; + public const int OBJECT_GROUP = 7; + public const int OBJECT_CREATOR = 8; + + // Can not be public const? + public static readonly vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0); + public static readonly rotation ZERO_ROTATION = new rotation(0.0, 0, 0.0, 1.0); + + // constants for llSetCameraParams + public const int CAMERA_PITCH = 0; + public const int CAMERA_FOCUS_OFFSET = 1; + public const int CAMERA_FOCUS_OFFSET_X = 2; + public const int CAMERA_FOCUS_OFFSET_Y = 3; + public const int CAMERA_FOCUS_OFFSET_Z = 4; + public const int CAMERA_POSITION_LAG = 5; + public const int CAMERA_FOCUS_LAG = 6; + public const int CAMERA_DISTANCE = 7; + public const int CAMERA_BEHINDNESS_ANGLE = 8; + public const int CAMERA_BEHINDNESS_LAG = 9; + public const int CAMERA_POSITION_THRESHOLD = 10; + public const int CAMERA_FOCUS_THRESHOLD = 11; + public const int CAMERA_ACTIVE = 12; + public const int CAMERA_POSITION = 13; + public const int CAMERA_POSITION_X = 14; + public const int CAMERA_POSITION_Y = 15; + public const int CAMERA_POSITION_Z = 16; + public const int CAMERA_FOCUS = 17; + public const int CAMERA_FOCUS_X = 18; + public const int CAMERA_FOCUS_Y = 19; + public const int CAMERA_FOCUS_Z = 20; + public const int CAMERA_POSITION_LOCKED = 21; + public const int CAMERA_FOCUS_LOCKED = 22; + + // constants for llGetParcelDetails + public const int PARCEL_DETAILS_NAME = 0; + public const int PARCEL_DETAILS_DESC = 1; + public const int PARCEL_DETAILS_OWNER = 2; + public const int PARCEL_DETAILS_GROUP = 3; + public const int PARCEL_DETAILS_AREA = 4; + + // constants for llSetClickAction + public const int CLICK_ACTION_NONE = 0; + public const int CLICK_ACTION_TOUCH = 0; + public const int CLICK_ACTION_SIT = 1; + public const int CLICK_ACTION_BUY = 2; + public const int CLICK_ACTION_PAY = 3; + public const int CLICK_ACTION_OPEN = 4; + public const int CLICK_ACTION_PLAY = 5; + public const int CLICK_ACTION_OPEN_MEDIA = 6; + } +} diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_OSSL/Commands_OSSL.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_OSSL/Commands_OSSL.cs index 6ba0c6376a..6b5dc14f9f 100644 --- a/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_OSSL/Commands_OSSL.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Commands_OSSL/Commands_OSSL.cs @@ -28,18 +28,17 @@ using System; using System.Collections.Generic; using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; +using OpenSim.ScriptEngine.Shared; namespace OpenSim.ScriptEngine.Components.DotNetEngine.Commands_OSSL { - public class Commands_OSSL: CommandBase + public class Commands_OSSL : IScriptEngineComponent { - public override void Start() + private RegionInfoStructure CurrentRegion; + public void Initialize(RegionInfoStructure currentRegion) { + CurrentRegion = currentRegion; } - public override void Close() - { - } } } diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs new file mode 100644 index 0000000000..e221e1bac6 --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs @@ -0,0 +1,186 @@ +/* + * 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 System.CodeDom.Compiler; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text.RegularExpressions; +using log4net; +using OpenSim.ScriptEngine.Shared; +using ScriptAssemblies; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers +{ + public abstract class CILCompiler + { + internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private string ScriptEnginesPath = "ScriptEngines"; + private string Name { get { return "SECS.DotNetEngine.CILCompiler"; } } + internal string ScriptAssemblyName { get; set; } + + // Default inherit + protected string ScriptInheritFrom = typeof(ScriptAssemblies.ScriptBase).Name; + private readonly System.Security.Cryptography.MD5CryptoServiceProvider MD5Sum = new System.Security.Cryptography.MD5CryptoServiceProvider(); + protected CodeDomProvider CompileProvider; + + //private string[] AppDomainAssemblies = new string[] { "OpenSim.Region.ScriptEngine.Shared.dll", "OpenSim.Region.ScriptEngine.Shared.Script.dll", "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll" }; + private readonly string[] AppDomainAssemblies = new string[] { + Assembly.GetAssembly(typeof(Int32)).Location, + "OpenSim.ScriptEngine.Shared.dll", + "OpenSim.ScriptEngine.Shared.Script.dll", + Path.Combine("ScriptEngines", "OpenSim.Region.ScriptEngine.Shared.dll") + }; + + public abstract string PreProcessScript(ref string script); + + public CILCompiler() + { + } + + private static readonly Regex FileNameFixer = new Regex(@"[^a-zA-Z0-9\.\-]", RegexOptions.Compiled | RegexOptions.Singleline); + public string Compile(ScriptMetaData data, ref string _script) + { + // Add "using", "inherit", default constructor, etc around script. + string script = PreProcessScript(ref _script); + + // Get filename based on content + string md5Sum = System.Convert.ToBase64String( + MD5Sum.ComputeHash( + System.Text.Encoding.ASCII.GetBytes(script) + )); + // Unique name for this assembly + ScriptAssemblyName = "SECS_Script_" + FileNameFixer.Replace(md5Sum, "_"); + + string OutFile = Path.Combine(ScriptEnginesPath, ScriptAssemblyName + ".dll"); + + // Make sure target dir exist + if (!Directory.Exists(ScriptEnginesPath)) + try { Directory.CreateDirectory(ScriptEnginesPath); } + catch { } + + // Already exist? No point in recompiling + if (File.Exists(OutFile)) + return OutFile; + + // + // Dump source code + // + string dumpFile = OutFile + ".txt"; + try + { + if (File.Exists(dumpFile)) + File.Delete(dumpFile); + File.WriteAllText(dumpFile, script); + } + catch (Exception e) + { + m_log.DebugFormat("[{0}] Exception trying to dump script source code to file \"{1}\": {2}", Name, dumpFile, e.ToString()); + } + + // + // COMPILE + // + + CompilerParameters parameters = new CompilerParameters(); + parameters.IncludeDebugInformation = true; + string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); + + foreach (string file in AppDomainAssemblies) + { + parameters.ReferencedAssemblies.Add(file); + m_log.DebugFormat("[{0}] Adding reference for compile: \"{1}\".", Name, file); + } + //lock (commandProvider) + //{ + // foreach (string key in commandProvider.Keys) + // { + // IScriptCommandProvider cp = commandProvider[key]; + // string + // file = cp.GetType().Assembly.Location; + // parameters.ReferencedAssemblies.Add(file); + // m_log.DebugFormat("[{0}] Loading command provider assembly \"{1}\" into AppDomain: \"{2}\".", Name, + // key, file); + // } + //} + + parameters.GenerateExecutable = false; + parameters.OutputAssembly = OutFile; + parameters.IncludeDebugInformation = true; + //parameters.WarningLevel = 1; // Should be 4? + parameters.TreatWarningsAsErrors = false; + + // Do compile + CompilerResults results = CompileProvider.CompileAssemblyFromSource(parameters, script); + + + // + // WARNINGS AND ERRORS + // + //TODO + int display = 5; + if (results.Errors.Count > 0) + { + string errtext = String.Empty; + foreach (CompilerError CompErr in results.Errors) + { + // Show 5 errors max + // + if (display <= 0) + break; + display--; + + string severity = "Error"; + if (CompErr.IsWarning) + severity = "Warning"; + + //TODO: Implement + KeyValuePair lslPos = new KeyValuePair(); + + //lslPos = "NOT IMPLEMENTED";// FindErrorPosition(CompErr.Line, CompErr.Column); + + string text = CompErr.ErrorText; + + // The Second Life viewer's script editor begins + // countingn lines and columns at 0, so we subtract 1. + errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n", + lslPos.Key - 1, lslPos.Value - 1, + CompErr.ErrorNumber, text, severity); + } + + if (!File.Exists(OutFile)) + { + throw new Exception(errtext); + } + } + + // TODO: Process errors + return OutFile; + } + + } +} diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_CS.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_CS.cs index 9c72359dfd..1286dc5e27 100644 --- a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_CS.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_CS.cs @@ -25,20 +25,46 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; +using Microsoft.CSharp; +using OpenSim.ScriptEngine.Shared; namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers { - public class Compiler_CS: CompilerBase + public class Compiler_CS : CILCompiler, IScriptCompiler { - public override void Start() + private string[] ScriptUsing = new string[] + { + "System", + "OpenSim.ScriptEngine.Shared", + "OpenSim.Region.ScriptEngine.Shared", + "System.Collections.Generic" + }; + + public Compiler_CS() { + CompileProvider = new CSharpCodeProvider(); } - public override void Close() + public override string PreProcessScript(ref string script) { + string s = ""; + foreach (string u in ScriptUsing) + { + s += "using " + u + ";"; + } + + s += "\r\n" + + String.Empty + "namespace ScriptAssemblies { " + + String.Empty + "public class UserScript" + " : " + ScriptInheritFrom + " { \r\n" + + @"public Script() { } " + + script + + "} }\r\n"; + + return s; } + } } diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_JS.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_JS.cs index 3dc8d8619e..5e9bfba4c1 100644 --- a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_JS.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_JS.cs @@ -25,20 +25,32 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; +using Microsoft.JScript; +using OpenSim.ScriptEngine.Shared; namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers { - public class Compiler_JS : CompilerBase + public class Compiler_JS : CILCompiler, IScriptCompiler { - public override void Start() + + public Compiler_JS() { + CompileProvider = new JScriptCodeProvider() as CodeDomProvider; } - public override void Close() + public override string PreProcessScript(ref string script) { + return + "import OpenSim.Region.ScriptEngine.Shared; import System.Collections.Generic;\r\n" + + "package SecondLife {\r\n" + + "class Script extends OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + + script + + "} }\r\n"; + } + } } diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_LSL.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_LSL.cs index 3354ce9bc7..d631c99511 100644 --- a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_LSL.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_LSL.cs @@ -26,19 +26,32 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; +using OpenSim.ScriptEngine.Components.DotNetEngine.Compilers.LSL; +using OpenSim.ScriptEngine.Shared; namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers { - public class Compiler_LSL : CompilerBase + public class Compiler_LSL : IScriptCompiler { - public override void Start() + + + private readonly Compiler_CS m_Compiler_CS = new Compiler_CS(); + private readonly LSL2CS m_LSL2CS = new LSL2CS(); + + public string Compile(ScriptMetaData scriptMetaData, ref string script) { + // Convert script to CS + string scriptCS = m_LSL2CS.Convert(ref script); + // Use CS compiler to compile it + return m_Compiler_CS.Compile(scriptMetaData, ref scriptCS); } - public override void Close() + public string PreProcessScript(ref string script) { + // This is handled by our converter + return script; } } } diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_VB.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_VB.cs index c7078cf18e..3975fa35d7 100644 --- a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_VB.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_VB.cs @@ -25,20 +25,32 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; +using Microsoft.VisualBasic; +using OpenSim.ScriptEngine.Shared; namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers { - public class Compiler_VB : CompilerBase + public class Compiler_VB : CILCompiler, IScriptCompiler { - public override void Start() + + public Compiler_VB() { + CompileProvider = new VBCodeProvider() as CodeDomProvider; } - public override void Close() + public override string PreProcessScript(ref string script) { + return + "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + + String.Empty + "NameSpace SecondLife:" + + String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + + "\r\nPublic Sub New()\r\nEnd Sub: " + + script + + ":End Class :End Namespace\r\n"; } } } + diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/Components/ComponentBase.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_YP.cs similarity index 70% rename from OpenSim/ApplicationPlugins/ScriptEngine/Components/ComponentBase.cs rename to OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_YP.cs index 48c6bfed46..c81ad761e1 100644 --- a/OpenSim/ApplicationPlugins/ScriptEngine/Components/ComponentBase.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/Compiler_YP.cs @@ -26,28 +26,30 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; +using OpenSim.ScriptEngine.Components.DotNetEngine.Compilers.YP; +using OpenSim.ScriptEngine.Shared; -namespace OpenSim.ApplicationPlugins.ScriptEngine.Components +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers { - /// - /// Generic baseclass for component providers - /// - public abstract class ComponentBase //: iProviderBase + public class Compiler_YP: IScriptCompiler { - //public abstract iProviderBase CreateInstance(); - public abstract void Start(); - public abstract void Close(); - public RegionScriptEngineBase scriptEngine; - public void Initialize(RegionScriptEngineBase ScriptEngine) + + private readonly Compiler_CS m_Compiler_CS = new Compiler_CS(); + + public string Compile(ScriptMetaData scriptMetaData, ref string script) { - scriptEngine = ScriptEngine; + // Convert script to CS + string scriptCS = YP2CS.Convert(ref script); + // Use CS compiler to compile it + return m_Compiler_CS.Compile(scriptMetaData, ref scriptCS); } - static ComponentBase() + public string PreProcessScript(ref string script) { - // We got loaded -- should we register now? - //OpenSim.ApplicationPlugins.ScriptEngine.ComponentProviders.providers.Add(GetType()); + // This is handled by our converter + return script; } } -} \ No newline at end of file +} diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/LSL/LSL2CS.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/LSL/LSL2CS.cs new file mode 100644 index 0000000000..0e8052df39 --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/LSL/LSL2CS.cs @@ -0,0 +1,44 @@ +/* + * 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 System.Collections.Generic; +using System.Text; +using OpenSim.Region.ScriptEngine.Shared.CodeTools; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers.LSL +{ + public class LSL2CS + { + private ICodeConverter Converter = new CSCodeGenerator(); + + public string Convert(ref string script) + { + //m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; + return Converter.Convert(script); + } + } +} diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/YP/YP2CS.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/YP/YP2CS.cs new file mode 100644 index 0000000000..e25a80031f --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/YP/YP2CS.cs @@ -0,0 +1,54 @@ +/* + * 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 System.Collections.Generic; +using System.Text; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers.YP +{ + public class YP2CS + { + public static string Convert(ref string script) + { + return script; + } + + public string PreProcessScript(ref string script) + { + return + "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + + "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + + String.Empty + "namespace SecondLife { " + + String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + + //@"public Script() { } " + + @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + + @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + + script + + "} }\r\n"; + } + } +} diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Events/LSLEventProvider.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Events/LSLEventProvider.cs index b42ceec684..794b132d18 100644 --- a/OpenSim/ScriptEngine/Components/DotNetEngine/Events/LSLEventProvider.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Events/LSLEventProvider.cs @@ -27,19 +27,92 @@ using System; using System.Collections.Generic; using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.ScriptEngine.Shared; +using EventParams=OpenSim.ScriptEngine.Shared.EventParams; namespace OpenSim.ScriptEngine.Components.DotNetEngine.Events { - public class LSLEventProvider: EventBase + public class LSLEventProvider : IScriptEventProvider { + public delegate void RezScriptDelegate(uint localID, UUID itemID, string script, int startParam, bool postOnRez, + string engine); + public event RezScriptDelegate RezScript; + public delegate void RemoveScriptDelegate(uint localID, UUID itemID); + public event RemoveScriptDelegate RemoveScript; + public delegate void ScriptChangedDelegate(uint localID, uint change); + public event ScriptChangedDelegate ScriptChanged; - public override void Start() + private RegionInfoStructure CurrentRegion; + public void Initialize(RegionInfoStructure currentRegion) { + CurrentRegion = currentRegion; + HookupEvents(); } - public override void Close() + private void HookupEvents() { + CurrentRegion.Scene.EventManager.OnObjectGrab += OnObjectGrab; + CurrentRegion.Scene.EventManager.OnRezScript += OnRezScript; + CurrentRegion.Scene.EventManager.OnRemoveScript += OnRemoveScript; + CurrentRegion.Scene.EventManager.OnScriptChangedEvent += OnScriptChangedEvent; + + + } + + private void OnScriptChangedEvent(uint localID, uint change) + { + // Script is being changed, fire event + if (ScriptChanged != null) + ScriptChanged(localID, change); + } + + private void OnRemoveScript(uint localID, UUID itemID) + { + // Script is being removed, fire event + if (RemoveScript != null) + RemoveScript(localID, itemID); + } + + private void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine) + { + // New script being created, fire event + if (RezScript != null) + RezScript(localID, itemID, script, startParam, postOnRez, engine); + } + + private void OnObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient) + { + // Add to queue for all scripts in ObjectID object + DetectParams[] det = new DetectParams[1]; + det[0] = new DetectParams(); + det[0].Key = remoteClient.AgentId; + //det[0].Populate(World); + + if (originalID == 0) + { + SceneObjectPart part = + CurrentRegion.Scene.GetSceneObjectPart(localID); + + if (part == null) + return; + + det[0].LinkNum = part.LinkNum; + } + else + { + SceneObjectPart originalPart = + CurrentRegion.Scene.GetSceneObjectPart(originalID); + det[0].LinkNum = originalPart.LinkNum; + } + + Shared.EventParams ep = + new Shared.EventParams(localID, "touch_start", new Object[] {new LSL_Types.LSLInteger(1)}, det); + CurrentRegion.Executors_Execute(ep); + } } } diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/BaseClassFactory.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/BaseClassFactory.cs new file mode 100644 index 0000000000..2f19caef50 --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/BaseClassFactory.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using OpenSim.ScriptEngine.Shared; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler +{ + public class BaseClassFactory + { + + + public static void MakeBaseClass(ScriptStructure script) + { + string asmName = "ScriptAssemblies"; + string ModuleID = asmName; + string ClassID = "Script"; + string moveToDir = "ScriptEngines"; + string asmFileName = ModuleID + "_" + ClassID + ".dll"; + if (!Directory.Exists(moveToDir)) + Directory.CreateDirectory(moveToDir); + + ILGenerator ilgen; + AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( + new AssemblyName(asmName), AssemblyBuilderAccess.RunAndSave); + + // The module builder + ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(ModuleID, asmFileName); + + // The class builder + TypeBuilder classBuilder = modBuilder.DefineType(ClassID, TypeAttributes.Class | TypeAttributes.Public); + + // The default constructor + ConstructorBuilder ctorBuilder = classBuilder.DefineDefaultConstructor(MethodAttributes.Public); + + + Type[] paramsTypeArray = new Type[] {typeof (System.ParamArrayAttribute)}; + Type[] executeFunctionTypeArray = new Type[] {typeof (string), typeof (System.ParamArrayAttribute)}; + foreach (IScriptCommandProvider cp in script.RegionInfo.CommandProviders.Values) + { + Type t = cp.GetType(); + foreach (MethodInfo mi in t.GetMethods()) + { + MethodBuilder methodBuilder = classBuilder.DefineMethod(mi.Name, mi.Attributes, mi.GetType(), Type.EmptyTypes); + methodBuilder.SetParameters(paramsTypeArray); + //ParameterBuilder paramBuilder = methodBuilder.DefineParameter(1, ParameterAttributes.None, "args"); + + ilgen = methodBuilder.GetILGenerator(); + //ilgen.Emit(OpCodes.Nop); + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Ldc_I4_0); + //ilgen.Emit(OpCodes.Ldelem_Ref); + //ilgen.MarkSequencePoint(doc, 6, 1, 6, 100); + + MethodInfo ExecuteFunction = typeof(ScriptAssemblies.IScript).GetMethod( + "ExecuteFunction", + executeFunctionTypeArray); + + ilgen.DeclareLocal(typeof(string)); + ilgen.Emit(OpCodes.Nop); + ilgen.Emit(OpCodes.Ldstr, mi.Name); + ilgen.Emit(OpCodes.Stloc_0); + ilgen.Emit(OpCodes.Ldarg_0); + ilgen.Emit(OpCodes.Ldloc_0); + ilgen.Emit(OpCodes.Ldarg_1); + + // FieldInfo testInfo = classBuilder. + //BindingFlags.NonPublic | BindingFlags.Instance); + + //ilgen.Emit(OpCodes.Ldfld, testInfo); + + //ilgen.EmitCall(OpCodes.Call, ExecuteFunction, executeFunctionTypeArray); + ilgen.EmitCall(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine"), executeFunctionTypeArray); + + // // string.Format("Hello, {0} World!", toWhom) + // // + // ilgen.Emit(OpCodes.Ldstr, "Hello, {0} World!"); + // ilgen.Emit(OpCodes.Ldarg_1); + // ilgen.Emit(OpCodes.Call, typeof(string).GetMethod + //("Format", new Type[] { typeof(string), typeof(object) })); + + // // Console.WriteLine("Hello, World!"); + // // + // ilgen.Emit(OpCodes.Call, typeof(Console).GetMethod + // ("WriteLine", new Type[] { typeof(string) })); + ilgen.Emit(OpCodes.Ret); + + + + //Label eom = ilgen.DefineLabel(); + //ilgen.Emit(OpCodes.Br_S, eom); + //ilgen.MarkLabel(eom); + //ilgen.Emit(OpCodes.Ret); + //Type test = methodBuilder.SetParameters(); + + + //methodBuilder.SetParameters(typeof (object[])); + + + } + } + + + //// Two fields: m_firstname, m_lastname + //FieldBuilder fBuilderFirstName = classBuilder.DefineField("m_firstname", typeof(string), FieldAttributes.Private); + //FieldBuilder fBuilderLastName = classBuilder.DefineField("m_lastname", typeof(string), FieldAttributes.Private); + + //// Two properties for this object: FirstName, LastName + //PropertyBuilder pBuilderFirstName = classBuilder.DefineProperty("FirstName", System.Reflection.PropertyAttributes.HasDefault, typeof(string), null); + //PropertyBuilder pBuilderLastName = classBuilder.DefineProperty("LastName", System.Reflection.PropertyAttributes.HasDefault, typeof(string), null); + + //// Custom attributes for get, set accessors + //MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName; + + //// get,set accessors for FirstName + //MethodBuilder mGetFirstNameBuilder = classBuilder.DefineMethod("get_FirstName", getSetAttr, typeof(string), Type.EmptyTypes); + + //// Code generation + //ilgen = mGetFirstNameBuilder.GetILGenerator(); + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Ldfld, fBuilderFirstName); // returning the firstname field + //ilgen.Emit(OpCodes.Ret); + + //MethodBuilder mSetFirstNameBuilder = classBuilder.DefineMethod("set_FirstName", getSetAttr, null, new Type[] { typeof(string) }); + + //// Code generation + //ilgen = mSetFirstNameBuilder.GetILGenerator(); + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Ldarg_1); + //ilgen.Emit(OpCodes.Stfld, fBuilderFirstName); // setting the firstname field from the first argument (1) + //ilgen.Emit(OpCodes.Ret); + + //// get,set accessors for LastName + //MethodBuilder mGetLastNameBuilder = classBuilder.DefineMethod("get_LastName", getSetAttr, typeof(string), Type.EmptyTypes); + + //// Code generation + //ilgen = mGetLastNameBuilder.GetILGenerator(); + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Ldfld, fBuilderLastName); // returning the firstname field + //ilgen.Emit(OpCodes.Ret); + + //MethodBuilder mSetLastNameBuilder = classBuilder.DefineMethod("set_LastName", getSetAttr, null, new Type[] { typeof(string) }); + + //// Code generation + //ilgen = mSetLastNameBuilder.GetILGenerator(); + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Ldarg_1); + //ilgen.Emit(OpCodes.Stfld, fBuilderLastName); // setting the firstname field from the first argument (1) + //ilgen.Emit(OpCodes.Ret); + + //// Assigning get/set accessors + //pBuilderFirstName.SetGetMethod(mGetFirstNameBuilder); + //pBuilderFirstName.SetSetMethod(mSetFirstNameBuilder); + + //pBuilderLastName.SetGetMethod(mGetLastNameBuilder); + //pBuilderLastName.SetSetMethod(mSetLastNameBuilder); + + //// Now, a custom method named GetFullName that concatenates FirstName and LastName properties + //MethodBuilder mGetFullNameBuilder = classBuilder.DefineMethod("GetFullName", MethodAttributes.Public, typeof(string), Type.EmptyTypes); + + //// Code generation + //ilgen = mGetFullNameBuilder.GetILGenerator(); + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Call, mGetFirstNameBuilder); // getting the firstname + //ilgen.Emit(OpCodes.Ldstr, " "); // an space + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Call, mGetLastNameBuilder); // getting the lastname + + //// We need the 'Concat' method from string type + //MethodInfo concatMethod = typeof(String).GetMethod("Concat", new Type[] { typeof(string), typeof(string), typeof(string) }); + + //ilgen.Emit(OpCodes.Call, concatMethod); // calling concat and returning the result + //ilgen.Emit(OpCodes.Ret); + + //// Another constructor that initializes firstname and lastname + //ConstructorBuilder ctorBuilder2 = classBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(string), typeof(string) }); + //ctorBuilder2.DefineParameter(1, ParameterAttributes.In, "firstname"); + //ctorBuilder2.DefineParameter(2, ParameterAttributes.In, "lastname"); + + //// Code generation + //ilgen = ctorBuilder2.GetILGenerator(); + + //// First of all, we need to call the base constructor, + //// the Object's constructor in this sample + //Type objType = Type.GetType("System.Object"); + //ConstructorInfo objCtor = objType.GetConstructor(Type.EmptyTypes); + + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Call, objCtor); // calling the Object's constructor + + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Ldarg_1); + //ilgen.Emit(OpCodes.Call, mSetFirstNameBuilder); // setting the firstname field from the first argument (1) + //ilgen.Emit(OpCodes.Ldarg_0); + //ilgen.Emit(OpCodes.Ldarg_2); + //ilgen.Emit(OpCodes.Call, mSetLastNameBuilder); // setting the lastname field from the second argument (2) + //ilgen.Emit(OpCodes.Ret); + + // Finally, create the type and save the assembly + classBuilder.CreateType(); + + asmBuilder.Save(asmFileName); + string toFile = Path.Combine(moveToDir, asmFileName); + if (File.Exists(toFile)) + File.Delete(toFile); + File.Move(asmFileName, toFile); + + string a = ""; + } + } +} \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/LoadUnloadStructure.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/LoadUnloadStructure.cs new file mode 100644 index 0000000000..d3d0509a5f --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/LoadUnloadStructure.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.ScriptEngine.Shared; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler +{ + public struct LoadUnloadStructure + { + public ScriptStructure Script; + public LUType Action; + public bool PostOnRez; + public int StartParam; + + public enum LUType + { + Unknown = 0, + Load = 1, + Unload = 2 + } + } +} diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/Scheduler.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/Scheduler.cs index 52c59eb61b..1143b034d3 100644 --- a/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/Scheduler.cs +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/Scheduler.cs @@ -27,18 +27,29 @@ using System; using System.Collections.Generic; using System.Text; -using OpenSim.ApplicationPlugins.ScriptEngine.Components; +using OpenMetaverse; +using OpenSim.ScriptEngine.Shared; namespace OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler { - public class Scheduler: SchedulerBase + public class Scheduler : IScriptScheduler { - public override void Start() + + private ScriptManager m_ScriptManager = new ScriptManager(); + public void AddScript(ScriptStructure scriptStructure) { + m_ScriptManager.AddScript(scriptStructure); } - public override void Close() + public void Removecript(uint id, UUID itemID) { + m_ScriptManager.RemoveScript(id, itemID); } + + public void Close() + { + m_ScriptManager.Close(); + } + } } diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptLoader.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptLoader.cs new file mode 100644 index 0000000000..cb4a870d11 --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptLoader.cs @@ -0,0 +1,216 @@ +/* + * 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 System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using log4net; +using OpenSim.ScriptEngine.Shared; +using IScript=OpenSim.Region.ScriptEngine.Shared.ScriptBase.IScript; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler +{ + public class ScriptLoader : IScriptLoader + { + // + // This class does AppDomain handling and loading/unloading of + // scripts in it. It is instanced in "ScriptEngine" and controlled + // from "ScriptManager" + // + // 1. Create a new AppDomain if old one is full (or doesn't exist) + // 2. Load scripts into AppDomain + // 3. Unload scripts from AppDomain (stopping them and marking + // them as inactive) + // 4. Unload AppDomain completely when all scripts in it has stopped + // + + public string Name { get { return "SECS.DotNetEngine.Scheduler.ScriptLoader"; } } + private int maxScriptsPerAppDomain = 10; + + // Internal list of all AppDomains + private List appDomains = + new List(); + private Dictionary AppDomainFiles = new Dictionary(); + public readonly string[] AssembliesInAppDomain = new string[] { "OpenSim.ScriptEngine.Shared.Script.dll", "OpenSim.Region.ScriptEngine.Shared.dll" }; + + internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + // Structure to keep track of data around AppDomain + private class AppDomainStructure + { + public AppDomain CurrentAppDomain; // The AppDomain itself + public int ScriptsLoaded; // Number of scripts loaded into AppDomain + public int ScriptsWaitingUnload; // Number of dead scripts + } + + // Current AppDomain + private AppDomainStructure currentAD; + + private object getLock = new object(); // Mutex + private object freeLock = new object(); // Mutex + + // Find a free AppDomain, creating one if necessary + private AppDomainStructure GetFreeAppDomain() + { + lock (getLock) + { + // Current full? + if (currentAD != null && + currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) + { + // Add it to AppDomains list and empty current + appDomains.Add(currentAD); + currentAD = null; + } + // No current + if (currentAD == null) + { + // Create a new current AppDomain + currentAD = new AppDomainStructure(); + currentAD.CurrentAppDomain = PrepareNewAppDomain(); + } + + return currentAD; + } + } + + private int AppDomainNameCount; + public ScriptAssemblies.IScript LoadScript(ScriptStructure script) + { + // Find next available AppDomain to put it in + AppDomainStructure FreeAppDomain; + + // If we already have loaded file, then reuse that AppDomains + if (AppDomainFiles.ContainsKey(script.AssemblyFileName)) + FreeAppDomain = AppDomainFiles[script.AssemblyFileName]; + else + FreeAppDomain = GetFreeAppDomain(); + + // Set script object AppDomain + script.AppDomain = FreeAppDomain.CurrentAppDomain; + + // Create instance of script + ScriptAssemblies.IScript mbrt = (ScriptAssemblies.IScript) + FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap( + script.AssemblyFileName, "ScriptAssemblies.Script"); + //, true, BindingFlags.CreateInstance, null); + FreeAppDomain.ScriptsLoaded++; + + return mbrt; + } + + // Create and prepare a new AppDomain for scripts + private AppDomain PrepareNewAppDomain() + { + // Create and prepare a new AppDomain + AppDomainNameCount++; + + // TODO: Currently security match current appdomain + + // Construct and initialize settings for a second AppDomain. + AppDomainSetup ads = new AppDomainSetup(); + ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; + ads.DisallowBindingRedirects = true; + ads.DisallowCodeDownload = true; + ads.LoaderOptimization = LoaderOptimization.MultiDomainHost; + ads.ShadowCopyFiles = "false"; // Disable shadowing + ads.ConfigurationFile = + AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; + + AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + + AppDomainNameCount, null, ads); + + foreach (string file in AssembliesInAppDomain) + { + m_log.InfoFormat("[{0}] AppDomain Loading: \"{1}\"->\"{2}\".", Name, file, + AssemblyName.GetAssemblyName(file).ToString()); + AD.Load(AssemblyName.GetAssemblyName(file)); + } + + // Return the new AppDomain + return AD; + } + + // Unload appdomains that are full and have only dead scripts + private void UnloadAppDomains() + { + lock (freeLock) + { + // Go through all + foreach (AppDomainStructure ads in new ArrayList(appDomains)) + { + // Don't process current AppDomain + if (ads.CurrentAppDomain != currentAD.CurrentAppDomain) + { + // Not current AppDomain + // Is number of unloaded bigger or equal to number of loaded? + if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload) + { + // Remove from internal list + appDomains.Remove(ads); + + // Unload + AppDomain.Unload(ads.CurrentAppDomain); + } + } + } + } + } + + // Increase "dead script" counter for an AppDomain + public void StopScript(AppDomain ad) + { + lock (freeLock) + { + // Check if it is current AppDomain + if (currentAD.CurrentAppDomain == ad) + { + // Yes - increase + currentAD.ScriptsWaitingUnload++; + return; + } + + // Lopp through all AppDomains + foreach (AppDomainStructure ads in new ArrayList(appDomains)) + { + if (ads.CurrentAppDomain == ad) + { + // Found it + ads.ScriptsWaitingUnload++; + break; + } + } + } + + UnloadAppDomains(); // Outsite lock, has its own GetLock + } + + + + } +} \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptManager.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptManager.cs new file mode 100644 index 0000000000..3452b0376e --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptManager.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using System.Text; +using System.Threading; +using log4net; +using OpenMetaverse; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.ScriptEngine.Shared; +using EventParams=OpenSim.ScriptEngine.Shared.EventParams; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler +{ + public partial class ScriptManager: IScriptExecutor + { + private const int NoWorkSleepMs = 50; + private const int NoWorkSleepMsInc = 1; // How much time to increase wait with on every iteration + private const int NoWorkSleepMsIncMax = 300; // Max time to wait + + internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public string Name { get { return "SECS.DotNetEngine.ScriptManager"; } } + private static Thread ScriptLoadUnloadThread; + public Dictionary> Scripts = new Dictionary>(); + + private RegionInfoStructure CurrentRegion; + public void Initialize(RegionInfoStructure currentRegion) + { + CurrentRegion = currentRegion; + } + + public ScriptManager() + { + ScriptLoadUnloadThread = new Thread(LoadUnloadLoop); + ScriptLoadUnloadThread.Name = "ScriptLoadUnloadThread"; + ScriptLoadUnloadThread.IsBackground = true; + ScriptLoadUnloadThread.Start(); + } + public void Close() { } + + private void LoadUnloadLoop () + { + int _NoWorkSleepMsInc = 0; + while (true) + { + if (DoScriptLoadUnload()) + { + // We found work, reset counter + _NoWorkSleepMsInc = NoWorkSleepMs; + } else + { + // We didn't find work + // Sleep + Thread.Sleep(NoWorkSleepMs + NoWorkSleepMsInc); + // Increase sleep delay + _NoWorkSleepMsInc += NoWorkSleepMsInc; + // Make sure we don't exceed max + if (_NoWorkSleepMsInc > NoWorkSleepMsIncMax) + _NoWorkSleepMsInc = NoWorkSleepMsIncMax; + } + } + } + + #region Add/Remove/Find script functions for our Script memory structure + private void MemAddScript(ScriptStructure script) + { + lock (scriptLock) + { + // Create object if it doesn't exist + if (!Scripts.ContainsKey(script.LocalID)) + Scripts.Add(script.LocalID, new Dictionary()); + + // Delete script if it exists + Dictionary Obj; + if (Scripts.TryGetValue(script.LocalID, out Obj)) + if (Obj.ContainsKey(script.ItemID) == true) + Obj.Remove(script.ItemID); + + // Add to object + Obj.Add(script.ItemID, script); + } + } + private void MemRemoveScript(uint LocalID, UUID ItemID) + { + // TODO: Also clean up command queue and async commands for object + lock (scriptLock) + { + // Create object if it doesn't exist + if (!Scripts.ContainsKey(LocalID)) + return; + + // Delete script if it exists + Dictionary Obj; + if (Scripts.TryGetValue(LocalID, out Obj)) + if (Obj.ContainsKey(ItemID) == true) + Obj.Remove(ItemID); + + // Empty? + if (Obj.Count == 0) + Scripts.Remove(LocalID); + + } + } + public bool TryGetScript(uint localID, UUID itemID, ref ScriptStructure script) + { + lock (scriptLock) + { + + if (Scripts.ContainsKey(localID) == false) + return false; + + Dictionary Obj; + if (Scripts.TryGetValue(localID, out Obj)) + if (Obj.ContainsKey(itemID) == false) + return false; + + // Get script + return Obj.TryGetValue(itemID, out script); + } + } + public ScriptStructure GetScript(uint localID, UUID itemID) + { + lock (scriptLock) + { + + if (Scripts.ContainsKey(localID) == false) + throw new Exception("No script with LocalID " + localID + " was found."); + + Dictionary Obj; + if (Scripts.TryGetValue(localID, out Obj)) + if (Obj.ContainsKey(itemID) == false) + throw new Exception("No script with ItemID " + itemID + " was found."); + + // Get script + return Obj[itemID]; + } + } + public bool TryGetScripts(uint localID, ref Dictionary returnList) + { + Dictionary getList = GetScripts(localID); + if (getList != null) + { + returnList = getList; + return true; + } + return false; + } + public Dictionary GetScripts(uint localID) + { + lock (scriptLock) + { + + if (Scripts.ContainsKey(localID) == false) + return null; + return Scripts[localID]; + } + } + #endregion + + public void ExecuteCommand(EventParams p) + { + ScriptStructure ss = new ScriptStructure(); + if (TryGetScript(p.LocalID, p.ItemID, ref ss)) + ExecuteCommand(ref ss, p); + } + + public void ExecuteCommand(ref ScriptStructure scriptContainer, EventParams p) + { + m_log.DebugFormat("[{0}] ######################################################", Name); + m_log.DebugFormat("[{0}] Command execution ItemID {1}: \"{2}\".", Name, scriptContainer.ItemID, p.EventName); + scriptContainer.ExecuteEvent(p); + m_log.DebugFormat("[{0}] ######################################################", Name); + } + + } +} diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptManager_ScriptLoadUnload.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptManager_ScriptLoadUnload.cs new file mode 100644 index 0000000000..7d362f9733 --- /dev/null +++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Scheduler/ScriptManager_ScriptLoadUnload.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Text; +using System.Threading; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.ScriptEngine.Shared; + +namespace OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler +{ + public partial class ScriptManager + { + private Queue LUQueue = new Queue(); + private int LoadUnloadMaxQueueSize = 500; + private Object scriptLock = new Object(); + //private Dictionary detparms = new Dictionary(); + + // Load/Unload structure + + + public void AddScript(ScriptStructure script) + { + lock (LUQueue) + { + if ((LUQueue.Count >= LoadUnloadMaxQueueSize)) + { + m_log.ErrorFormat("[{0}] ERROR: Load queue count is at {1} of max {2}. Ignoring load request for script LocalID: {3}, ItemID: {4}.", + Name, LUQueue.Count, LoadUnloadMaxQueueSize, script.LocalID, script.ItemID); + return; + } + + LoadUnloadStructure ls = new LoadUnloadStructure(); + ls.Script = script; + ls.Action = LoadUnloadStructure.LUType.Load; + LUQueue.Enqueue(ls); + } + + } + public void RemoveScript(uint localID, UUID itemID) + { + LoadUnloadStructure ls = new LoadUnloadStructure(); + + // See if we can find script + if (!TryGetScript(localID, itemID, ref ls.Script)) + { + // Set manually + ls.Script.LocalID = localID; + ls.Script.ItemID = itemID; + } + ls.Script.StartParam = 0; + + ls.Action = LoadUnloadStructure.LUType.Unload; + ls.PostOnRez = false; + + lock (LUQueue) + { + LUQueue.Enqueue(ls); + } + } + + internal bool DoScriptLoadUnload() + { + bool ret = false; + // if (!m_started) + // return; + + lock (LUQueue) + { + if (LUQueue.Count > 0) + { + LoadUnloadStructure item = LUQueue.Dequeue(); + ret = true; + + if (item.Action == LoadUnloadStructure.LUType.Unload) + { + m_log.DebugFormat("[{0}] Unloading script", Name); + _StopScript(item.Script.LocalID, item.Script.ItemID); + RemoveScript(item.Script.LocalID, item.Script.ItemID); + } + else if (item.Action == LoadUnloadStructure.LUType.Load) + { + m_log.DebugFormat("[{0}] Loading script", Name); + _StartScript(item); + } + } + } + return ret; + } + + //public void _StartScript(uint localID, UUID itemID, string Script, int startParam, bool postOnRez) + private void _StartScript(LoadUnloadStructure ScriptObject) + { + m_log.DebugFormat( + "[{0}]: ScriptManager StartScript: localID: {1}, itemID: {2}", + Name, ScriptObject.Script.LocalID, ScriptObject.Script.ItemID); + + // We will initialize and start the script. + // It will be up to the script itself to hook up the correct events. + + SceneObjectPart m_host = ScriptObject.Script.RegionInfo.Scene.GetSceneObjectPart(ScriptObject.Script.LocalID); + + if (null == m_host) + { + m_log.ErrorFormat( + "[{0}]: Could not find scene object part corresponding " + + "to localID {1} to start script", + Name, ScriptObject.Script.LocalID); + + return; + } + + UUID assetID = UUID.Zero; + TaskInventoryItem taskInventoryItem = new TaskInventoryItem(); + if (m_host.TaskInventory.TryGetValue(ScriptObject.Script.ItemID, out taskInventoryItem)) + assetID = taskInventoryItem.AssetID; + + ScenePresence presence = + ScriptObject.Script.RegionInfo.Scene.GetScenePresence(taskInventoryItem.OwnerID); + + CultureInfo USCulture = new CultureInfo("en-US"); + Thread.CurrentThread.CurrentCulture = USCulture; + + try + { + // + // Compile script to an assembly + // + //TODO: DEBUG + BaseClassFactory.MakeBaseClass(ScriptObject.Script); + + m_log.DebugFormat("[{0}] Compiling script {1}", Name, ScriptObject.Script.Name); + + string fileName = ""; + try + { + IScriptCompiler compiler = + ScriptObject.Script.RegionInfo.FindCompiler(ScriptObject.Script.ScriptMetaData); + RegionInfoStructure currentRegionInfo = ScriptObject.Script.RegionInfo; + fileName = compiler.Compile(ScriptObject.Script.ScriptMetaData, + ref ScriptObject.Script.Source); + ScriptObject.Script.AssemblyFileName = fileName; + } + catch (Exception e) + { + m_log.ErrorFormat("[{0}] Internal error while compiling \"{1}\": {2}", Name, ScriptObject.Script.Name, e.ToString()); + } + m_log.DebugFormat("[{0}] Compiled \"{1}\" to assembly: \"{2}\".", Name, ScriptObject.Script.Name, fileName); + + // Add it to our script memstruct + MemAddScript(ScriptObject.Script); + + ScriptAssemblies.IScript CompiledScript; + CompiledScript = CurrentRegion.ScriptLoader.LoadScript(ScriptObject.Script); + ScriptObject.Script.State = "default"; + ScriptObject.Script.ScriptObject = CompiledScript; + ScriptObject.Script.Disabled = false; + ScriptObject.Script.Running = true; + //id.LineMap = LSLCompiler.LineMap(); + //id.Script = CompiledScript; + //id.Source = item.Script.Script; + //item.StartParam = startParam; + + + + // TODO: Fire the first start-event + //int eventFlags = + // m_scriptEngine.m_ScriptManager.GetStateEventFlags( + // localID, itemID); + + //m_host.SetScriptEvents(itemID, eventFlags); + ScriptObject.Script.RegionInfo.Executors_Execute(ScriptObject.Script, + new EventParams(ScriptObject.Script.LocalID, ScriptObject.Script.ItemID, "state_entry", new object[] { }, new Region.ScriptEngine.Shared.DetectParams[0]) + ); + + if (ScriptObject.PostOnRez) + { + ScriptObject.Script.RegionInfo.Executors_Execute(ScriptObject.Script, + new EventParams(ScriptObject.Script.LocalID, "on_rez", new object[] + {new Region.ScriptEngine.Shared.LSL_Types.LSLInteger(ScriptObject.StartParam) + }, new Region.ScriptEngine.Shared.DetectParams[0])); + } + } + catch (Exception e) // LEGIT: User Scripting + { + if (presence != null && (!ScriptObject.PostOnRez)) + presence.ControllingClient.SendAgentAlertMessage( + "Script saved with errors, check debug window!", + false); + try + { + // DISPLAY ERROR INWORLD + string text = "Error compiling script:\n" + + e.Message.ToString(); + if (text.Length > 1100) + text = text.Substring(0, 1099); + + ScriptObject.Script.RegionInfo.Scene.SimChat(Utils.StringToBytes(text), + ChatTypeEnum.DebugChannel, 2147483647, + m_host.AbsolutePosition, m_host.Name, m_host.UUID, + false); + } + catch (Exception e2) // LEGIT: User Scripting + { + m_log.Error("[" + + Name + + "]: Error displaying error in-world: " + + e2.ToString()); + m_log.Error("[" + + Name + "]: " + + "Errormessage: Error compiling script:\r\n" + + e2.Message.ToString()); + } + } + } + + + + public void _StopScript(uint localID, UUID itemID) + { + ScriptStructure ss = new ScriptStructure(); + if (!TryGetScript(localID, itemID, ref ss)) + return; + + // Stop long command on script + //AsyncCommandManager.RemoveScript(ss); + + try + { + // Get AppDomain + // Tell script not to accept new requests + ss.Running = false; + ss.Disabled = true; + AppDomain ad = ss.AppDomain; + + // Remove from internal structure + MemRemoveScript(localID, itemID); + + // TODO: Tell AppDomain that we have stopped script + + } + catch (Exception e) // LEGIT: User Scripting + { + m_log.Error("[" + + Name + + "]: Exception stopping script localID: " + + localID + " LLUID: " + itemID.ToString() + + ": " + e.ToString()); + } + } + + + } +} diff --git a/OpenSim/ScriptEngine/Engines/DotNetEngine/DotNetEngine.cs b/OpenSim/ScriptEngine/Engines/DotNetEngine/DotNetEngine.cs index 3f2476347a..0f9b964698 100644 --- a/OpenSim/ScriptEngine/Engines/DotNetEngine/DotNetEngine.cs +++ b/OpenSim/ScriptEngine/Engines/DotNetEngine/DotNetEngine.cs @@ -28,47 +28,170 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using log4net; using Nini.Config; +using OpenMetaverse; using OpenSim.ApplicationPlugins.ScriptEngine; using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Scenes; -using ComponentProviders = OpenSim.ApplicationPlugins.ScriptEngine.ComponentRegistry; +using OpenSim.ScriptEngine.Components.DotNetEngine.Events; +using OpenSim.ScriptEngine.Components.DotNetEngine.Scheduler; +using OpenSim.ScriptEngine.Shared; +using ComponentProviders = OpenSim.ApplicationPlugins.ScriptEngine; namespace OpenSim.ScriptEngine.Engines.DotNetEngine { // This is a sample engine - public class DotNetEngine : RegionScriptEngineBase + public partial class DotNetEngine : IScriptEngine { - - // This will be the makeup of this script engine - public string[] ComponentNames = new string[] { - "Commands_LSL", - "Commands_OSSL", - "Compiler_CS", - "Compiler_JS", - "Compiler_LSL", - "Compiler_VB", - "LSLEventProvider", - "Scheduler" - }; + //private string[] _ComponentNames = new string[] { + // "Commands_LSL", + // "Commands_OSSL", + // "Compiler_CS", + // "Compiler_JS", + // "Compiler_LSL", + // "Compiler_VB", + // "LSLEventProvider", + // "Scheduler" + // }; + internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public override string Name + public string Name { get { return "SECS.DotNetEngine"; } } + //public bool IsSharedModule { get { return true; } } + internal RegionInfoStructure RegionInfo; + + private string[] commandNames = new string[] + { + "Commands_LSL" + }; + + private string[] compilerNames = new string[] + { + "Compiler_CS", + "Compiler_JS", + "Compiler_LSL", + "Compiler_YP", + "Compiler_VB" + }; + private string[] schedulerNames = new string[] + { + "Scheduler" + }; + + //internal IScriptLoader m_ScriptLoader; + internal LSLEventProvider m_LSLEventProvider; + //internal IScriptExecutor m_Executor; + //internal Dictionary Compilers = new Dictionary(); + internal Dictionary Schedulers = new Dictionary(); + public static Dictionary Compilers = new Dictionary(); +// private static bool haveInitialized = false; + + public DotNetEngine() { - get { return "DotNetEngine"; } + RegionInfo = new RegionInfoStructure(); + RegionInfo.Compilers = Compilers; + RegionInfo.Schedulers = Schedulers; + RegionInfo.Executors = new Dictionary(); + RegionInfo.CommandProviders = new Dictionary(); + RegionInfo.EventProviders = new Dictionary(); + RegionInfo.Logger = LogManager.GetLogger("SECS.DotNetEngine.RegionInfo"); } - public override void Initialize() + public void Initialise(Scene scene, IConfigSource source) { - // We need to initialize the components we will be using. Our baseclass already has builtin functions for this. - m_log.Info("[" + Name + "]: Initializing SECs (Script Engine Components)"); - InitializeComponents(ComponentNames); + RegionInfo.Scene = scene; + RegionInfo.ConfigSource = source; + + m_log.DebugFormat("[{0}] Initializing components", Name); + InitializeComponents(); } - public override void PreClose() + public void PostInitialise() { } + + /// + /// Called on region close + /// + public void Close() { - // Before + ComponentClose(); } + #region Initialize the Script Engine Components we need + public void InitializeComponents() + { + string cname = ""; + m_log.DebugFormat("[{0}] Component initialization", Name); + // Initialize an instance of all module we want + try + { + cname = "ScriptManager"; + m_log.DebugFormat("[{0}] Executor: {1}", Name, cname); + RegionInfo.Executors.Add(cname, + ScriptEnginePlugin.GetComponentInstance(RegionInfo, cname) as IScriptExecutor); + + cname = "ScriptLoader"; + m_log.DebugFormat("[{0}] ScriptLoader: {1}", Name, cname); + RegionInfo.ScriptLoader = + ScriptEnginePlugin.GetComponentInstance(RegionInfo, cname) as IScriptExecutor as ScriptLoader; + + // CommandProviders + foreach (string cn in commandNames) + { + cname = cn; + m_log.DebugFormat("[{0}] CommandProvider: {1}", Name, cname); + RegionInfo.CommandProviders.Add(cname, + ScriptEnginePlugin.GetComponentInstance(RegionInfo, cname) as + IScriptCommandProvider); + } + + // Compilers + foreach (string cn in compilerNames) + { + cname = cn; + m_log.DebugFormat("[{0}] Compiler: {1}", Name, cname); + RegionInfo.Compilers.Add(cname, + ScriptEnginePlugin.GetComponentInstance(RegionInfo, cname) as + IScriptCompiler); + } + + // Schedulers + foreach (string cn in schedulerNames) + { + cname = cn; + m_log.DebugFormat("[{0}] Scheduler: {1}", Name, cname); + RegionInfo.Schedulers.Add(cname, + ScriptEnginePlugin.GetComponentInstance(RegionInfo, cname) as + IScriptScheduler); + } + + // Event provider + cname = "LSLEventProvider"; + m_log.DebugFormat("[{0}] EventProvider: {1}", Name, cname); + IScriptEventProvider sep = ScriptEnginePlugin.GetComponentInstance(RegionInfo, cname) as IScriptEventProvider; + RegionInfo.EventProviders.Add(cname, sep); + m_LSLEventProvider = sep as LSLEventProvider; + + // Hook up events + m_LSLEventProvider.RezScript += Events_RezScript; + m_LSLEventProvider.RemoveScript += Events_RemoveScript; + } + catch (Exception e) + { + m_log.ErrorFormat("[{0}] Exception while loading \"{1}\": {2}", Name, cname, e.ToString()); + } + } + + private void ComponentClose() + { + // Close schedulers + foreach (IScriptScheduler scheduler in RegionInfo.Schedulers.Values) + { + scheduler.Close(); + } + } + + #endregion + } } diff --git a/OpenSim/ScriptEngine/Engines/DotNetEngine/DotNetEngine_ScriptLoadUnload.cs b/OpenSim/ScriptEngine/Engines/DotNetEngine/DotNetEngine_ScriptLoadUnload.cs new file mode 100644 index 0000000000..bf429f6725 --- /dev/null +++ b/OpenSim/ScriptEngine/Engines/DotNetEngine/DotNetEngine_ScriptLoadUnload.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; +using OpenSim.ScriptEngine.Components.DotNetEngine.Events; +using OpenSim.ScriptEngine.Shared; + +namespace OpenSim.ScriptEngine.Engines.DotNetEngine +{ + public partial class DotNetEngine + { + + //internal Dictionary ScriptMapping = new Dictionary(); + + + // + // HANDLE EVENTS FROM SCRIPTS + // We will handle script add, change and remove events outside of command pipeline + // + #region Script Add/Change/Remove + void Events_RezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine) + { + // ### + // # New script created + // ### + m_log.DebugFormat( + "[{0}] NEW SCRIPT: localID: {1}, itemID: {2}, startParam: {3}, postOnRez: {4}, engine: {5}", + Name, localID, itemID, startParam, postOnRez, engine); + + // Make a script object + ScriptStructure scriptObject = new ScriptStructure(); + scriptObject.RegionInfo = RegionInfo; + scriptObject.LocalID = localID; + scriptObject.ItemID = itemID; + scriptObject.Source = script; + + // + // Get MetaData from script header + // + ScriptMetaData scriptMetaData = ScriptMetaData.Extract(ref script); + scriptObject.ScriptMetaData = scriptMetaData; + foreach (string key in scriptObject.ScriptMetaData.Keys) + { + m_log.DebugFormat("[{0}] Script metadata: Key: \"{1}\", Value: \"{2}\".", Name, key, scriptObject.ScriptMetaData[key]); + } + + // + // Load this assembly + // + // TODO: Use Executor to send a command instead? + m_log.DebugFormat("[{0}] Adding script to scheduler", Name); + RegionInfo.FindScheduler(scriptObject.ScriptMetaData).AddScript(scriptObject); + // Add to our internal mapping + //ScriptMapping.Add(itemID, Schedulers[scheduler]); + } + + private void Events_RemoveScript(uint localID, UUID itemID) + { + // Tell all schedulers to remove this item + foreach (IScriptScheduler scheduler in RegionInfo.Schedulers.Values) + { + scheduler.Removecript(localID, itemID); + } + } + #endregion + + } +} diff --git a/OpenSim/ScriptEngine/Shared.Script/ICommandProvider.cs b/OpenSim/ScriptEngine/Shared.Script/ICommandProvider.cs new file mode 100644 index 0000000000..fefb5f9a88 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared.Script/ICommandProvider.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ScriptAssemblies +{ + public interface ICommandProvider + { + void ExecuteCommand(string functionName, params object[] args); + string Name { get; } + } +} diff --git a/OpenSim/ScriptEngine/Shared.Script/IScript.cs b/OpenSim/ScriptEngine/Shared.Script/IScript.cs new file mode 100644 index 0000000000..5a3d3f3e05 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared.Script/IScript.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ScriptAssemblies +{ + public interface IScript + { + void ExecuteFunction(string functionName, params object[] args); + } +} \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Shared.Script/Properties/AssemblyInfo.cs b/OpenSim/ScriptEngine/Shared.Script/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..96b6c0c0ce --- /dev/null +++ b/OpenSim/ScriptEngine/Shared.Script/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.ScriptEngine.Shared.Script")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("OpenSim.ScriptEngine.Shared.Script")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ea77002b-c967-4368-ace9-6533f8147d4b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/ScriptEngine/Shared.Script/ScriptBase.cs b/OpenSim/ScriptEngine/Shared.Script/ScriptBase.cs new file mode 100644 index 0000000000..587314f78b --- /dev/null +++ b/OpenSim/ScriptEngine/Shared.Script/ScriptBase.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Remoting.Lifetime; +using System.Text; + +namespace ScriptAssemblies +{ + public class ScriptBase : MarshalByRefObject, IScript + { + + #region AppDomain Serialization Keep-Alive + // + // Never expire this object + // + public override Object InitializeLifetimeService() + { + ILease lease = (ILease)base.InitializeLifetimeService(); + + if (lease.CurrentState == LeaseState.Initial) + { + lease.InitialLeaseTime = TimeSpan.Zero; + } + return lease; + } + #endregion + + public delegate void ExecuteFunctionEventDelegate(string functionName, params object[] args); + public event ExecuteFunctionEventDelegate OnExecuteFunction; + + private List CommandProviders = new List(); + + public ScriptBase() + { + } + + public void ExecuteFunction(string functionName, params object[] args) + { + // We got a new command, fire event + if (OnExecuteFunction != null) + OnExecuteFunction(functionName, args); + + } + } +} diff --git a/OpenSim/ScriptEngine/Shared/EventParams.cs b/OpenSim/ScriptEngine/Shared/EventParams.cs new file mode 100644 index 0000000000..661086ec92 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/EventParams.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; +using OpenSim.Region.ScriptEngine.Shared; + +namespace OpenSim.ScriptEngine.Shared +{ + /// + /// Holds all the data required to execute a scripting event. + /// + public class EventParams + { + public string EventName; + public Object[] Params; + public Region.ScriptEngine.Shared.DetectParams[] DetectParams; + public uint LocalID; + public UUID ItemID; + + public EventParams(uint localID, UUID itemID, string eventName, Object[] eventParams, DetectParams[] detectParams) + { + LocalID = localID; + ItemID = itemID; + EventName = eventName; + Params = eventParams; + DetectParams = detectParams; + } + public EventParams(uint localID, string eventName, Object[] eventParams, DetectParams[] detectParams) + { + LocalID = localID; + EventName = eventName; + Params = eventParams; + DetectParams = detectParams; + } + public void test(params object[] args) + { + string functionName = "test"; + test2(functionName, args); + } + public void test2(string functionName, params object[] args) + { + System.Console.WriteLine(functionName, args); + } + + + } +} \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Shared/IScriptCommandProvider.cs b/OpenSim/ScriptEngine/Shared/IScriptCommandProvider.cs new file mode 100644 index 0000000000..f37fcaf66d --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/IScriptCommandProvider.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.ScriptEngine.Shared +{ + public interface IScriptCommandProvider : ScriptAssemblies.ICommandProvider + { + } +} diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/Components/EventBase.cs b/OpenSim/ScriptEngine/Shared/IScriptCompiler.cs similarity index 82% rename from OpenSim/ApplicationPlugins/ScriptEngine/Components/EventBase.cs rename to OpenSim/ScriptEngine/Shared/IScriptCompiler.cs index 1c0fd52c12..3bc0c03d2e 100644 --- a/OpenSim/ApplicationPlugins/ScriptEngine/Components/EventBase.cs +++ b/OpenSim/ScriptEngine/Shared/IScriptCompiler.cs @@ -26,20 +26,15 @@ */ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; +using ScriptAssemblies; -namespace OpenSim.ApplicationPlugins.ScriptEngine.Components +namespace OpenSim.ScriptEngine.Shared { - public abstract class EventBase : ComponentBase + public interface IScriptCompiler : IScriptEngineComponent { - //public override iProviderBase CreateInstance() - //{ - // throw new NotImplementedException(); - //} - - //public override void Start() - //{ - // throw new NotImplementedException(); - //} + string Compile(ScriptMetaData scriptMetaData, ref string script); + string PreProcessScript(ref string script); } } \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Shared/IScriptEngine.cs b/OpenSim/ScriptEngine/Shared/IScriptEngine.cs new file mode 100644 index 0000000000..6148d8d7f6 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/IScriptEngine.cs @@ -0,0 +1,49 @@ +/* + * 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 System.Collections.Generic; +using System.Text; +using Nini.Config; +using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.ScriptEngine.Shared +{ + public interface IScriptEngine + { + //string[] ComponentNames { get; } + //Dictionary Components { get; } + //void InitializeComponents(); + void Initialise(Scene scene, IConfigSource source); + void PostInitialise(); + void Close(); + string Name { get; } + // string Name { get; } + //void Initialize(); + //void Close(); + } +} \ No newline at end of file diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/Components/CommandBase.cs b/OpenSim/ScriptEngine/Shared/IScriptEngineComponent.cs similarity index 82% rename from OpenSim/ApplicationPlugins/ScriptEngine/Components/CommandBase.cs rename to OpenSim/ScriptEngine/Shared/IScriptEngineComponent.cs index 470855413d..3c977a5df2 100644 --- a/OpenSim/ApplicationPlugins/ScriptEngine/Components/CommandBase.cs +++ b/OpenSim/ScriptEngine/Shared/IScriptEngineComponent.cs @@ -28,18 +28,9 @@ using System; using System.Collections.Generic; using System.Text; -namespace OpenSim.ApplicationPlugins.ScriptEngine.Components +namespace OpenSim.ScriptEngine.Shared { - public abstract class CommandBase: ComponentBase + public interface IScriptEngineComponent { - //public override iProviderBase CreateInstance() - //{ - // throw new NotImplementedException(); - //} - - //public override void Start() - //{ - // throw new NotImplementedException(); - //} } } \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Shared/IScriptEngineRegionComponent.cs b/OpenSim/ScriptEngine/Shared/IScriptEngineRegionComponent.cs new file mode 100644 index 0000000000..a8d779d889 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/IScriptEngineRegionComponent.cs @@ -0,0 +1,7 @@ +namespace OpenSim.ScriptEngine.Shared +{ + public interface IScriptEngineRegionComponent + { + void Initialize(RegionInfoStructure currentRegion); + } +} diff --git a/OpenSim/ScriptEngine/Shared/IScriptEventProvider.cs b/OpenSim/ScriptEngine/Shared/IScriptEventProvider.cs new file mode 100644 index 0000000000..a290ba4f8f --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/IScriptEventProvider.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.ScriptEngine.Shared +{ + public interface IScriptEventProvider : IScriptEngineComponent, IScriptEngineRegionComponent + { + + } +} \ No newline at end of file diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/Components/CompilerBase.cs b/OpenSim/ScriptEngine/Shared/IScriptExecutor.cs similarity index 82% rename from OpenSim/ApplicationPlugins/ScriptEngine/Components/CompilerBase.cs rename to OpenSim/ScriptEngine/Shared/IScriptExecutor.cs index e62d1f2b10..77bea1305b 100644 --- a/OpenSim/ApplicationPlugins/ScriptEngine/Components/CompilerBase.cs +++ b/OpenSim/ScriptEngine/Shared/IScriptExecutor.cs @@ -27,19 +27,13 @@ using System; using System.Collections.Generic; using System.Text; +using OpenSim.ScriptEngine.Shared; -namespace OpenSim.ApplicationPlugins.ScriptEngine.Components +namespace OpenSim.ScriptEngine.Shared { - public abstract class CompilerBase: ComponentBase + public interface IScriptExecutor : IScriptEngineComponent, IScriptEngineRegionComponent { - //public override iProviderBase CreateInstance() - //{ - // throw new NotImplementedException(); - //} - - //public override void Start() - //{ - // throw new NotImplementedException(); - //} + void ExecuteCommand(ref ScriptStructure scriptContainer, EventParams p); + void ExecuteCommand(EventParams p); } } \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Shared/IScriptLoader.cs b/OpenSim/ScriptEngine/Shared/IScriptLoader.cs new file mode 100644 index 0000000000..15f7443097 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/IScriptLoader.cs @@ -0,0 +1,9 @@ +using OpenSim.ScriptEngine.Shared; + +namespace OpenSim.ScriptEngine.Shared +{ + public interface IScriptLoader: IScriptEngineComponent + { + ScriptAssemblies.IScript LoadScript(ScriptStructure script); + } +} \ No newline at end of file diff --git a/OpenSim/ApplicationPlugins/ScriptEngine/Components/SchedulerBase.cs b/OpenSim/ScriptEngine/Shared/IScriptScheduler.cs similarity index 82% rename from OpenSim/ApplicationPlugins/ScriptEngine/Components/SchedulerBase.cs rename to OpenSim/ScriptEngine/Shared/IScriptScheduler.cs index 9d5aff0895..3e56c1262a 100644 --- a/OpenSim/ApplicationPlugins/ScriptEngine/Components/SchedulerBase.cs +++ b/OpenSim/ScriptEngine/Shared/IScriptScheduler.cs @@ -27,19 +27,15 @@ using System; using System.Collections.Generic; using System.Text; +using OpenMetaverse; +using OpenSim.ScriptEngine.Shared; -namespace OpenSim.ApplicationPlugins.ScriptEngine.Components +namespace OpenSim.ScriptEngine.Shared { - public abstract class SchedulerBase: ComponentBase + public interface IScriptScheduler : IScriptEngineComponent { - //public override iProviderBase CreateInstance() - //{ - // throw new NotImplementedException(); - //} - - //public override void Start() - //{ - // throw new NotImplementedException(); - //} + void AddScript(ScriptStructure script); + void Removecript(uint id, UUID itemID); + void Close(); } } \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Shared/Properties/AssemblyInfo.cs b/OpenSim/ScriptEngine/Shared/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..06a3461256 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.ScriptEngine.Shared")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("OpenSim.ScriptEngine.Shared")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ea77002b-c967-4368-ace9-6533f8147d4b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/ScriptEngine/Shared/RegionInfoStructure.cs b/OpenSim/ScriptEngine/Shared/RegionInfoStructure.cs new file mode 100644 index 0000000000..834fac3043 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/RegionInfoStructure.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.ScriptEngine.Shared; +using EventParams=OpenSim.ScriptEngine.Shared.EventParams; + +namespace OpenSim.ScriptEngine.Shared +{ + public struct RegionInfoStructure + { + public Scene Scene; + public IConfigSource ConfigSource; + + public IScriptLoader ScriptLoader; + public Dictionary EventProviders; + public Dictionary Executors; + public Dictionary Compilers; + public Dictionary Schedulers; + public Dictionary CommandProviders; + public ILog Logger; + + public void Executors_Execute(EventParams p) + { + // Execute a command on all executors + lock (Executors) + { + foreach (IScriptExecutor exec in Executors.Values) + { + exec.ExecuteCommand(p); + } + } + } + public void Executors_Execute(ScriptStructure scriptContainer, EventParams p) + { + // Execute a command on all executors + lock (Executors) + { + foreach (IScriptExecutor exec in Executors.Values) + { + exec.ExecuteCommand(ref scriptContainer, p); + } + } + } + + public IScriptCompiler FindCompiler(ScriptMetaData scriptMetaData) + { + string compiler = "Compiler_LSL"; + if (scriptMetaData.ContainsKey("Compiler")) + compiler = scriptMetaData["Compiler"]; + + lock (Compilers) + { + if (!Compilers.ContainsKey(compiler)) + throw new Exception("Requested script compiler \"" + compiler + "\" does not exist."); + + return Compilers[compiler]; + } + } + + public IScriptScheduler FindScheduler(ScriptMetaData scriptMetaData) + { + string scheduler = "Scheduler"; + if (scriptMetaData.ContainsKey("Scheduler")) + scheduler = scriptMetaData["Scheduler"]; + + lock (Schedulers) + { + if (!Schedulers.ContainsKey(scheduler)) + throw new Exception("Requested script scheduler \"" + scheduler + "\" does not exist."); + + return Schedulers[scheduler]; + } + } + + //public Assembly[] GetCommandProviderAssemblies() + //{ + // lock (CommandProviders) + // { + // Assembly[] ass = new Assembly[CommandProviders.Count]; + // int i = 0; + // foreach (string key in CommandProviders.Keys) + // { + // ass[i] = CommandProviders[key].GetType().Assembly; + // i++; + // } + // return ass; + // } + //} + } +} \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Shared/ScriptMetaData.cs b/OpenSim/ScriptEngine/Shared/ScriptMetaData.cs new file mode 100644 index 0000000000..462f2d4ef0 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/ScriptMetaData.cs @@ -0,0 +1,95 @@ +/* + * 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 System.Collections.Generic; + +namespace OpenSim.ScriptEngine.Shared +{ + public class ScriptMetaData: Dictionary + { + private static readonly char[] LineSeparator = "\r\n".ToCharArray(); + private static readonly char[] Separator = { ':' }; + public static ScriptMetaData Extract(ref string Script) + { + ScriptMetaData ret = new ScriptMetaData(); + if (string.IsNullOrEmpty(Script)) + return ret; + + // Process it line by line + string Line = ""; + for (int i = 0; i < Script.Length + 1; i++) + { + // Found a line separator? + if (i < Script.Length + && Script[i] != LineSeparator[0] + && Script[i] != LineSeparator[1]) + { + // No, not end of line. Add to current line + Line += Script[i]; + } + else + { + // Extract MetaData from this line. Returns False if not found. + if (!_GetMetaFromLine(ret, Line)) + continue; + // Empty for next round + Line = ""; + } + } + return ret; + } + + private static bool _GetMetaFromLine(ScriptMetaData ret, string line) + { + line = line.Trim(); + + // Empty line? We may find more later + if (line == "") + return true; + + // Is this a comment? If not, then return false + if (!line.StartsWith("//")) + return false; + + // It is a comment + string[] keyval = line.Split(Separator, 2, StringSplitOptions.None); + keyval[0] = keyval[0].Substring(2, keyval[0].Length - 2).Trim(); + keyval[1] = keyval[1].Trim(); + + // Add it + if (keyval[0] != "") + if (!ret.ContainsKey(keyval[0])) + { + //m_log.DebugFormat("[DotNetEngine] Script metadata: Key: \"{0}\", Value: \"{1}\".", keyval[0], keyval[1]); + ret.Add(keyval[0], keyval[1]); + } + + return true; + } + + } +} \ No newline at end of file diff --git a/OpenSim/ScriptEngine/Shared/ScriptStructure.cs b/OpenSim/ScriptEngine/Shared/ScriptStructure.cs new file mode 100644 index 0000000000..cbf333b716 --- /dev/null +++ b/OpenSim/ScriptEngine/Shared/ScriptStructure.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using OpenMetaverse; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.ScriptEngine.Shared; + +namespace OpenSim.ScriptEngine.Shared +{ + public struct ScriptStructure + { + public RegionInfoStructure RegionInfo; + public ScriptMetaData ScriptMetaData; + + public ScriptAssemblies.IScript ScriptObject; + public string State; + public bool Running; + public bool Disabled; + public string Source; + public int StartParam; + public AppDomain AppDomain; + public Dictionary Apis; + public Dictionary, KeyValuePair> LineMap; + public uint LocalID; + public UUID ItemID; + public string AssemblyFileName; + + public string ScriptID { get { return LocalID.ToString() + "." + ItemID.ToString(); } } + public string Name { get { return "Script:" + ScriptID; } } + private bool Initialized; + private Dictionary InternalFunctions; + public string AssemblyName; + + public void ExecuteEvent(EventParams p) + { + ExecuteMethod(p, true); + } + + public void ExecuteMethod(EventParams p) + { + ExecuteMethod(p, false); + } + private void ExecuteMethod(EventParams p, bool isEvent) + { + // First time initialization? + if (!Initialized) + { + Initialized = true; + CacheInternalFunctions(); + } + + lock (InternalFunctions) + { + // Make function name + string FunctionName; + if (isEvent) + FunctionName = State + "_event_" + p.EventName; + else + FunctionName = p.EventName; + + // Check if this function exist + if (!InternalFunctions.ContainsKey(FunctionName)) + { + // TODO: Send message in-world + //RegionInfo.Scene. + RegionInfo.Logger.ErrorFormat("[{0}] Script function \"{1}\" was not found.", Name, FunctionName); + return; + } + + // Execute script function + try + { + InternalFunctions[FunctionName].DynamicInvoke(p.Params); + } + catch (Exception e) + { + RegionInfo.Logger.ErrorFormat("[{0}] Execute \"{1}\" failed: {2}", Name, FunctionName, e.ToString()); + } + } + } + + /// + /// Cache functions into a dictionary with delegates. Should be faster than reflection. + /// + private void CacheInternalFunctions() + { + Type scriptObjectType = ScriptObject.GetType(); + InternalFunctions = new Dictionary(); + + MethodInfo[] methods = scriptObjectType.GetMethods(); + lock (InternalFunctions) + { + // Read all methods into a dictionary + foreach (MethodInfo mi in methods) + { + // TODO: We don't support overloading + if (!InternalFunctions.ContainsKey(mi.Name)) + InternalFunctions.Add(mi.Name, Delegate.CreateDelegate(scriptObjectType, ScriptObject, mi)); + else + RegionInfo.Logger.ErrorFormat("[{0}] Error: Script function \"{1}\" is already added. We do not support overloading.", + Name, mi.Name); + } + } + } + + } +} \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index 7ca00d6a31..f3af10b4c5 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2205,6 +2205,66 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2218,7 +2278,6 @@ ../../../bin/ - ../../../bin/ScriptEngines/ @@ -2227,20 +2286,20 @@ - - - - - + + + + + @@ -2250,17 +2309,16 @@ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ ../../../../../bin/ - ../../../../../bin/ScriptEngines/ @@ -2274,12 +2332,11 @@ - - - - + + + @@ -2291,17 +2348,16 @@ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ ../../../../../bin/ - ../../../../../bin/ScriptEngines/ @@ -2315,12 +2371,11 @@ - - - - + + + @@ -2332,12 +2387,12 @@ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ @@ -2356,12 +2411,13 @@ - - - - + + + + + @@ -2373,17 +2429,16 @@ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ ../../../../../bin/ - ../../../../../bin/ScriptEngines/ @@ -2397,12 +2452,12 @@ - - - - + + + + @@ -2414,12 +2469,12 @@ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ - ../../../../../bin/ScriptEngines/ + ../../../../../bin/ @@ -2438,12 +2493,11 @@ - - - - + + + @@ -2455,12 +2509,12 @@ - ../../../../bin/ScriptEngines/ + ../../../../bin/ - ../../../../bin/ScriptEngines/ + ../../../../bin/ @@ -2479,12 +2533,16 @@ - - - - + + + + + + + +