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