aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
authorMelanie Thielker2008-09-21 21:47:00 +0000
committerMelanie Thielker2008-09-21 21:47:00 +0000
commit94aaf67dfaafbcbd4d871f674c465a34c1c1f332 (patch)
tree33476e5660a95bdf7d29d14beae67a6294af28a7 /OpenSim/Region/ScriptEngine
parent* minor: warnings removal (diff)
downloadopensim-SC_OLD-94aaf67dfaafbcbd4d871f674c465a34c1c1f332.zip
opensim-SC_OLD-94aaf67dfaafbcbd4d871f674c465a34c1c1f332.tar.gz
opensim-SC_OLD-94aaf67dfaafbcbd4d871f674c465a34c1c1f332.tar.bz2
opensim-SC_OLD-94aaf67dfaafbcbd4d871f674c465a34c1c1f332.tar.xz
Change the scirpt engine loading mechanism. Script engines are now
ordinary region modules and are able to coexist in one instance. See http://opensimulator.org/wiki/ScriptEngines for details. There were changes to OpenSim.ini.example, please note DefaultScriptEngine. Also see the User docs and FAQ on the Wiki. Default is DotNetEngine.
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs50
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs24
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptServerInterfaces.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs43
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/LSL2CSConverter.cs374
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs30
8 files changed, 95 insertions, 441 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
index 5a9385f..4a4e808 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
@@ -65,31 +65,36 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
65 myScriptEngine = _ScriptEngine; 65 myScriptEngine = _ScriptEngine;
66 ReadConfig(); 66 ReadConfig();
67 67
68 // Hook up to events from OpenSim
69 // We may not want to do it because someone is controlling us and will deliver events to us
70 if (performHookUp) 68 if (performHookUp)
71 { 69 {
72 myScriptEngine.Log.Info("[" + myScriptEngine.ScriptEngineName + "]: Hooking up to server events");
73 myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
74 myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end;
75 myScriptEngine.World.EventManager.OnRezScript += OnRezScript; 70 myScriptEngine.World.EventManager.OnRezScript += OnRezScript;
76 myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript; 71 }
77 myScriptEngine.World.EventManager.OnScriptChangedEvent += changed; 72 }
78 myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target; 73
79 myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; 74 public void HookUpEvents()
80 myScriptEngine.World.EventManager.OnScriptControlEvent += control; 75 {
81 myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; 76 // Hook up to events from OpenSim
82 myScriptEngine.World.EventManager.OnScriptColliding += collision; 77 // We may not want to do it because someone is controlling us and will deliver events to us
83 myScriptEngine.World.EventManager.OnScriptCollidingEnd += collision_end;
84
85 // TODO: HOOK ALL EVENTS UP TO SERVER!
86 IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>();
87 if (money != null)
88 {
89 money.OnObjectPaid+=HandleObjectPaid;
90 }
91 78
79 myScriptEngine.Log.Info("[" + myScriptEngine.ScriptEngineName + "]: Hooking up to server events");
80 myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
81 myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end;
82 myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript;
83 myScriptEngine.World.EventManager.OnScriptChangedEvent += changed;
84 myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target;
85 myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target;
86 myScriptEngine.World.EventManager.OnScriptControlEvent += control;
87 myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start;
88 myScriptEngine.World.EventManager.OnScriptColliding += collision;
89 myScriptEngine.World.EventManager.OnScriptCollidingEnd += collision_end;
90
91 // TODO: HOOK ALL EVENTS UP TO SERVER!
92 IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>();
93 if (money != null)
94 {
95 money.OnObjectPaid+=HandleObjectPaid;
92 } 96 }
97
93 } 98 }
94 99
95 public void ReadConfig() 100 public void ReadConfig()
@@ -187,8 +192,11 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
187 myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "touch_end", detstruct, new object[] { new LSL_Types.LSLInteger(1) }); 192 myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "touch_end", detstruct, new object[] { new LSL_Types.LSLInteger(1) });
188 } 193 }
189 194
190 public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez) 195 public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine)
191 { 196 {
197 if (engine != "DotNetEngine")
198 return;
199
192 myScriptEngine.Log.Debug("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " + 200 myScriptEngine.Log.Debug("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " +
193 script.Length); 201 script.Length);
194 myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script, startParam, postOnRez); 202 myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script, startParam, postOnRez);
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
index af7fca3..282559a 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
@@ -353,6 +353,11 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
353 /// <param name="param">Array of parameters to match event mask</param> 353 /// <param name="param">Array of parameters to match event mask</param>
354 public void AddToScriptQueue(uint localID, UUID itemID, string FunctionName, Queue_llDetectParams_Struct qParams, params object[] param) 354 public void AddToScriptQueue(uint localID, UUID itemID, string FunctionName, Queue_llDetectParams_Struct qParams, params object[] param)
355 { 355 {
356 List<UUID> keylist = new List<UUID>(m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID));
357
358 if (!keylist.Contains(itemID)) // We don't manage that script
359 return;
360
356 lock (eventQueue) 361 lock (eventQueue)
357 { 362 {
358 if (eventQueue.Count >= EventExecutionMaxQueueSize) 363 if (eventQueue.Count >= EventExecutionMaxQueueSize)
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
index b0c6314..26e5ec2 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
@@ -56,6 +56,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
56 public IConfigSource ConfigSource; 56 public IConfigSource ConfigSource;
57 public IConfig ScriptConfigSource; 57 public IConfig ScriptConfigSource;
58 public abstract string ScriptEngineName { get; } 58 public abstract string ScriptEngineName { get; }
59 private bool m_enabled = true;
60 private bool m_hookUpToServer = false;
59 61
60 /// <summary> 62 /// <summary>
61 /// How many seconds between re-reading config-file. 0 = never. ScriptEngine will try to adjust to new config changes. 63 /// How many seconds between re-reading config-file. 0 = never. ScriptEngine will try to adjust to new config changes.
@@ -91,6 +93,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
91 { 93 {
92 World = Sceneworld; 94 World = Sceneworld;
93 ConfigSource = config; 95 ConfigSource = config;
96 m_hookUpToServer = HookUpToServer;
97
94 m_log.Info("[" + ScriptEngineName + "]: ScriptEngine initializing"); 98 m_log.Info("[" + ScriptEngineName + "]: ScriptEngine initializing");
95 99
96 // Make sure we have config 100 // Make sure we have config
@@ -98,13 +102,16 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
98 ConfigSource.AddConfig(ScriptEngineName); 102 ConfigSource.AddConfig(ScriptEngineName);
99 ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; 103 ScriptConfigSource = ConfigSource.Configs[ScriptEngineName];
100 104
105 m_enabled = ScriptConfigSource.GetBoolean("Enabled", true);
106 if (!m_enabled)
107 return;
108
101 //m_log.Info("[" + ScriptEngineName + "]: InitializeEngine"); 109 //m_log.Info("[" + ScriptEngineName + "]: InitializeEngine");
102 110
103 // Create all objects we'll be using 111 // Create all objects we'll be using
104 m_EventQueueManager = new EventQueueManager(this); 112 m_EventQueueManager = new EventQueueManager(this);
105 m_EventManager = new EventManager(this, HookUpToServer); 113 m_EventManager = new EventManager(this, HookUpToServer);
106 // We need to start it 114 // We need to start it
107 newScriptManager.Start();
108 m_ScriptManager = newScriptManager; 115 m_ScriptManager = newScriptManager;
109 m_AppDomainManager = new AppDomainManager(this); 116 m_AppDomainManager = new AppDomainManager(this);
110 m_ASYNCLSLCommandManager = new AsyncCommandManager(this); 117 m_ASYNCLSLCommandManager = new AsyncCommandManager(this);
@@ -118,6 +125,17 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
118 // Or can we assume we are loaded before anything else so we can use proper events? 125 // Or can we assume we are loaded before anything else so we can use proper events?
119 } 126 }
120 127
128 public void PostInitialise()
129 {
130 if (!m_enabled)
131 return;
132
133 if (m_hookUpToServer)
134 m_EventManager.HookUpEvents();
135
136 m_ScriptManager.Start();
137 }
138
121 public void Shutdown() 139 public void Shutdown()
122 { 140 {
123 // We are shutting down 141 // We are shutting down
@@ -155,10 +173,6 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
155 173
156 public abstract void Initialise(Scene scene, IConfigSource config); 174 public abstract void Initialise(Scene scene, IConfigSource config);
157 175
158 public void PostInitialise()
159 {
160 }
161
162 public void Close() 176 public void Close()
163 { 177 {
164 } 178 }
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
index 60333b1..47cb2fd 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
@@ -64,6 +64,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
64 private static bool PrivateThread; 64 private static bool PrivateThread;
65 private int LoadUnloadMaxQueueSize; 65 private int LoadUnloadMaxQueueSize;
66 private Object scriptLock = new Object(); 66 private Object scriptLock = new Object();
67 private bool m_started = false;
67 68
68 // Load/Unload structure 69 // Load/Unload structure
69 private struct LUStruct 70 private struct LUStruct
@@ -119,6 +120,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
119 public abstract void Initialize(); 120 public abstract void Initialize();
120 public void Start() 121 public void Start()
121 { 122 {
123 m_started = true;
124
122 ReadConfig(); 125 ReadConfig();
123 Initialize(); 126 Initialize();
124 127
@@ -213,6 +216,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
213 216
214 public void DoScriptLoadUnload() 217 public void DoScriptLoadUnload()
215 { 218 {
219 if (!m_started)
220 return;
221
216 lock (LUQueue) 222 lock (LUQueue)
217 { 223 {
218 if (LUQueue.Count > 0) 224 if (LUQueue.Count > 0)
@@ -258,7 +264,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
258 { 264 {
259 lock (LUQueue) 265 lock (LUQueue)
260 { 266 {
261 if (LUQueue.Count >= LoadUnloadMaxQueueSize) 267 if ((LUQueue.Count >= LoadUnloadMaxQueueSize) && m_started)
262 { 268 {
263 m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: ERROR: Load/unload queue item count is at " + LUQueue.Count + ". Config variable \"LoadUnloadMaxQueueSize\" is set to " + LoadUnloadMaxQueueSize + ", so ignoring new script."); 269 m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: ERROR: Load/unload queue item count is at " + LUQueue.Count + ". Config variable \"LoadUnloadMaxQueueSize\" is set to " + LoadUnloadMaxQueueSize + ", so ignoring new script.");
264 return; 270 return;
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptServerInterfaces.cs b/OpenSim/Region/ScriptEngine/Common/ScriptServerInterfaces.cs
index a6473ee..aa8dc61 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptServerInterfaces.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptServerInterfaces.cs
@@ -39,7 +39,7 @@ namespace OpenSim.Region.ScriptEngine.Common
39 public interface RemoteEvents 39 public interface RemoteEvents
40 { 40 {
41 void touch_start(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient); 41 void touch_start(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient);
42 void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez); 42 void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine);
43 void OnRemoveScript(uint localID, UUID itemID); 43 void OnRemoveScript(uint localID, UUID itemID);
44 void state_exit(uint localID); 44 void state_exit(uint localID);
45 void touch(uint localID, uint originalID, UUID itemID); 45 void touch(uint localID, uint originalID, UUID itemID);
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index c88cd05..b14e7ac 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -82,7 +82,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
82 82
83 // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files 83 // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files
84 private static UInt64 scriptCompileCounter = 0; // And a counter 84 private static UInt64 scriptCompileCounter = 0; // And a counter
85 private bool m_UseCompiler = true;
86 85
87 public IScriptEngine m_scriptEngine; 86 public IScriptEngine m_scriptEngine;
88 public Compiler(IScriptEngine scriptEngine) 87 public Compiler(IScriptEngine scriptEngine)
@@ -93,8 +92,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
93 public bool in_startup = true; 92 public bool in_startup = true;
94 public void ReadConfig() 93 public void ReadConfig()
95 { 94 {
96 m_UseCompiler = m_scriptEngine.Config.GetBoolean("UseNewCompiler", true);
97
98 // Get some config 95 // Get some config
99 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", true); 96 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", true);
100 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); 97 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true);
@@ -327,14 +324,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
327 { 324 {
328 // Its LSL, convert it to C# 325 // Its LSL, convert it to C#
329 //compileScript = LSL_Converter.Convert(Script); 326 //compileScript = LSL_Converter.Convert(Script);
330 if (m_UseCompiler) 327 LSL_Converter = (ICodeConverter)new CSCodeGenerator();
331 LSL_Converter = (ICodeConverter)new CSCodeGenerator();
332 else
333 LSL_Converter = (ICodeConverter)new LSL2CSConverter();
334 compileScript = LSL_Converter.Convert(Script); 328 compileScript = LSL_Converter.Convert(Script);
335 329
336 if (m_UseCompiler) 330 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap;
337 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap;
338 331
339 l = enumCompileType.cs; 332 l = enumCompileType.cs;
340 } 333 }
@@ -549,31 +542,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
549 severity = "Warning"; 542 severity = "Warning";
550 } 543 }
551 544
552 if (m_UseCompiler) 545 KeyValuePair<int, int> lslPos;
553 {
554 KeyValuePair<int, int> lslPos;
555
556 try
557 {
558 lslPos = m_positionMap[new KeyValuePair<int, int>(CompErr.Line, CompErr.Column)];
559 }
560 catch (KeyNotFoundException) // we don't have this line/column mapped
561 {
562 m_scriptEngine.Log.Debug(String.Format("[Compiler]: Lookup of C# line {0}, column {1} failed.", CompErr.Line, CompErr.Column));
563 lslPos = new KeyValuePair<int, int>(-CompErr.Line, -CompErr.Column);
564 }
565
566 // The Second Life viewer's script editor begins
567 // countingn lines and columns at 0, so we subtract 1.
568 errtext += String.Format("Line {0}, column {1}, {4} Number: {2}, '{3}'\r\n", lslPos.Key - 1, lslPos.Value - 1, CompErr.ErrorNumber, CompErr.ErrorText, severity);
569 546
547 try
548 {
549 lslPos = m_positionMap[new KeyValuePair<int, int>(CompErr.Line, CompErr.Column)];
570 } 550 }
571 else 551 catch (KeyNotFoundException) // we don't have this line/column mapped
572 { 552 {
573 errtext += "Line number " + (CompErr.Line - LinesToRemoveOnError) + 553 m_scriptEngine.Log.Debug(String.Format("[Compiler]: Lookup of C# line {0}, column {1} failed.", CompErr.Line, CompErr.Column));
574 ", " + severity + " Number: " + CompErr.ErrorNumber + 554 lslPos = new KeyValuePair<int, int>(-CompErr.Line, -CompErr.Column);
575 ", '" + CompErr.ErrorText + "'\r\n";
576 } 555 }
556
557 // The Second Life viewer's script editor begins
558 // countingn lines and columns at 0, so we subtract 1.
559 errtext += String.Format("Line {0}, column {1}, {4} Number: {2}, '{3}'\r\n", lslPos.Key - 1, lslPos.Value - 1, CompErr.ErrorNumber, CompErr.ErrorText, severity);
577 } 560 }
578 561
579 Console.WriteLine("[COMPILER MESSAGES]: " + errtext); 562 Console.WriteLine("[COMPILER MESSAGES]: " + errtext);
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSL2CSConverter.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSL2CSConverter.cs
deleted file mode 100644
index 57efb2e..0000000
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSL2CSConverter.cs
+++ /dev/null
@@ -1,374 +0,0 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.Collections.Generic;
31using System.Text.RegularExpressions;
32
33namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
34{
35 public class LSL2CSConverter : ICodeConverter
36 {
37 // Uses regex to convert LSL code to C# code.
38
39 //private Regex rnw = new Regex(@"[a-zA-Z0-9_\-]", RegexOptions.Compiled);
40 private Dictionary<string, string> dataTypes = new Dictionary<string, string>();
41 private Dictionary<string, string> quotes = new Dictionary<string, string>();
42 // c Style
43 private Regex cstylecomments = new Regex(@"/\*(.|[\r\n])*?\*/", RegexOptions.Compiled | RegexOptions.Multiline);
44 // c# one liners
45 private Regex nonCommentFwsl = new Regex("\"[a-zA-Z0-9.,:/\\n ]+//[^\"+]+([\\\\\\\"+]+)?(\\s+)?[\"+](\\s+)?(;)?", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
46 private Regex conelinecomments = new Regex(@"[^:].?([\/]{2}[^\n]*)|([\n]{1,}[\/]{2}[^\n]*)", RegexOptions.Compiled | RegexOptions.Multiline);
47 // ([^\"])((?:[a-zA-Z])\.[a-zA-Z].?)([^\"])
48
49 // value we're looking for: (?:[a-zA-Z])\.[a-zA-Z]
50 public LSL2CSConverter()
51 {
52 // Only the types we need to convert
53 dataTypes.Add("void", "void");
54 dataTypes.Add("integer", "LSL_Types.LSLInteger");
55 dataTypes.Add("float", "LSL_Types.LSLFloat");
56 dataTypes.Add("string", "LSL_Types.LSLString");
57 dataTypes.Add("key", "LSL_Types.LSLString");
58 dataTypes.Add("vector", "LSL_Types.Vector3");
59 dataTypes.Add("rotation", "LSL_Types.Quaternion");
60 dataTypes.Add("list", "LSL_Types.list");
61 dataTypes.Add("null", "null");
62 }
63
64 public string Convert(string Script)
65 {
66 quotes.Clear();
67 string Return = String.Empty;
68 Script = " \r\n" + Script;
69
70 //
71 // Prepare script for processing
72 //
73
74 // Clean up linebreaks
75 Script = Regex.Replace(Script, @"\r\n", "\n");
76 Script = Regex.Replace(Script, @"\n", "\r\n");
77
78 // QUOTE REPLACEMENT
79 // temporarily replace quotes so we can work our magic on the script without
80 // always considering if we are inside our outside quotes's
81 // TODO: Does this work on half-quotes in strings? ;)
82 string _Script = String.Empty;
83 string C;
84 bool in_quote = false;
85 bool quote_replaced = false;
86 string quote_replacement_string = "Q_U_O_T_E_REPLACEMENT_";
87 string quote = String.Empty;
88 bool last_was_escape = false;
89 int quote_replaced_count = 0;
90
91 string removefwnoncomments = nonCommentFwsl.Replace(Script, "\"\";");
92
93 string removecomments = conelinecomments.Replace(removefwnoncomments, "");
94 removecomments = cstylecomments.Replace(removecomments, "");
95 string[] localscript = removecomments.Split('"');
96 string checkscript = String.Empty;
97 bool flip = true;
98
99 for (int p = 0; p < localscript.Length; p++)
100 {
101 //if (localscript[p].Length >= 1)
102 //{
103 if (!localscript[p].EndsWith(@"\"))
104 {
105 flip = !flip;
106 //System.Console.WriteLine("Flip:" + flip.ToString() + " - " + localscript[p] + " ! " + localscript[p].EndsWith(@"\").ToString());
107 }
108 //}
109 //else
110 //{
111 // flip = !flip;
112 // System.Console.WriteLine("Flip:" + flip.ToString() + " - " + localscript[p]);
113 //}
114 if (!flip)
115 checkscript += localscript[p];
116 }
117
118 //System.Console.WriteLine("SCRIPT:" + checkscript);
119
120 // checks for alpha.alpha way of referring to objects in C#
121 // ignores alpha.X alpha.Y, alpha.Z for refering to vector components
122 Match SecurityM;
123
124 // BROKEN: this check is very wrong. It block's any url in strings.
125 SecurityM = Regex.Match(checkscript, @"(?:[a-zA-Z])\.(?:[a-rt-wA-Z]|[a-zA-Z][a-zA-Z])", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
126
127 if (SecurityM.Success)
128 throw new Exception("CS0103: 'The . symbol cannot be used in LSL except in float values or vector components'. Detected around: " + SecurityM.Captures[0].Value);
129
130 SecurityM = Regex.Match(checkscript, @"typeof\s", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
131 if (SecurityM.Success)
132 throw new Exception("CS0103: 'The object.typeof method isn't allowed in LSL'");
133
134 SecurityM = Regex.Match(checkscript, @"GetType\(", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
135 if (SecurityM.Success)
136 throw new Exception("CS0103: 'The object.GetType method isn't allowed in LSL'");
137
138 for (int p = 0; p < Script.Length; p++)
139 {
140 C = Script.Substring(p, 1);
141 while (true)
142 {
143 // found " and last was not \ so this is not an escaped \"
144 if (C == "\"" && last_was_escape == false)
145 {
146 // Toggle inside/outside quote
147 in_quote = !in_quote;
148 if (in_quote)
149 {
150 quote_replaced_count++;
151 }
152 else
153 {
154 if (quote == String.Empty)
155 {
156 // We didn't replace quote, probably because of empty string?
157 _Script += quote_replacement_string +
158 quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
159 }
160 // We just left a quote
161 quotes.Add(
162 quote_replacement_string +
163 quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]), quote);
164 quote = String.Empty;
165 }
166 break;
167 }
168
169 if (!in_quote)
170 {
171 // We are not inside a quote
172 quote_replaced = false;
173 }
174 else
175 {
176 // We are inside a quote
177 if (!quote_replaced)
178 {
179 // Replace quote
180 _Script += quote_replacement_string +
181 quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
182 quote_replaced = true;
183 }
184 quote += C;
185 break;
186 }
187 _Script += C;
188 break;
189 }
190 last_was_escape = false;
191 if (C == @"\")
192 {
193 last_was_escape = true;
194 }
195 }
196 Script = _Script;
197 //
198 // END OF QUOTE REPLACEMENT
199 //
200
201 //
202 // PROCESS STATES
203 // Remove state definitions and add state names to start of each event within state
204 //
205 int ilevel = 0;
206 int lastlevel = 0;
207 string ret = String.Empty;
208 string cache = String.Empty;
209 bool in_state = false;
210 string current_statename = String.Empty;
211 for (int p = 0; p < Script.Length; p++)
212 {
213 C = Script.Substring(p, 1);
214 while (true)
215 {
216 // inc / dec level
217 if (C == @"{")
218 ilevel++;
219 if (C == @"}")
220 ilevel--;
221 if (ilevel < 0)
222 ilevel = 0;
223 cache += C;
224
225 // if level == 0, add to return
226 if (ilevel == 1 && lastlevel == 0)
227 {
228 // 0 => 1: Get last
229 Match m =
230 //Regex.Match(cache, @"(?![a-zA-Z_]+)\s*([a-zA-Z_]+)[^a-zA-Z_\(\)]*{",
231 Regex.Match(cache, @"(?![a-zA-Z_]+)\s*(state\s+)?(?<statename>[a-zA-Z_][a-zA-Z_0-9]*)[^a-zA-Z_0-9\(\)]*{",
232
233 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
234
235 in_state = false;
236 if (m.Success)
237 {
238 // Go back to level 0, this is not a state
239 in_state = true;
240 current_statename = m.Groups["statename"].Captures[0].Value;
241 //Console.WriteLine("Current statename: " + current_statename);
242 cache =
243 //@"(?<s1>(?![a-zA-Z_]+)\s*)" + @"([a-zA-Z_]+)(?<s2>[^a-zA-Z_\(\)]*){",
244 Regex.Replace(cache,
245 @"(?<s1>(?![a-zA-Z_]+)\s*)" + @"(state\s+)?([a-zA-Z_][a-zA-Z_0-9]*)(?<s2>[^a-zA-Z_0-9\(\)]*){",
246 "${s1}${s2}",
247 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
248 }
249 ret += cache;
250 cache = String.Empty;
251 }
252 if (ilevel == 0 && lastlevel == 1)
253 {
254 // 1 => 0: Remove last }
255 if (in_state == true)
256 {
257 cache = cache.Remove(cache.Length - 1, 1);
258 //cache = Regex.Replace(cache, "}$", String.Empty, RegexOptions.Multiline | RegexOptions.Singleline);
259
260 //Replace function names
261 // void dataserver(key query_id, string data) {
262 //cache = Regex.Replace(cache, @"([^a-zA-Z_]\s*)((?!if|switch|for)[a-zA-Z_]+\s*\([^\)]*\)[^{]*{)", "$1" + "<STATE>" + "$2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
263 //Console.WriteLine("Replacing using statename: " + current_statename);
264 cache =
265 Regex.Replace(cache,
266 @"^(\s*)((?!(if|switch|for|while)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
267 @"$1public " + current_statename + "_event_$2",
268 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
269 }
270
271 ret += cache;
272 cache = String.Empty;
273 in_state = true;
274 current_statename = String.Empty;
275 }
276
277 break;
278 }
279 lastlevel = ilevel;
280 }
281 ret += cache;
282 cache = String.Empty;
283
284 Script = ret;
285 ret = String.Empty;
286
287 foreach (string key in dataTypes.Keys)
288 {
289 string val;
290 dataTypes.TryGetValue(key, out val);
291
292 // Replace CAST - (integer) with (int)
293 Script =
294 Regex.Replace(Script, @"\(" + key + @"\)", @"(" + val + ")",
295 RegexOptions.Compiled | RegexOptions.Multiline);
296 // Replace return types and function variables - integer a() and f(integer a, integer a)
297 Script =
298 Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s+)", @"$1$2" + val + "$3",
299 RegexOptions.Compiled | RegexOptions.Multiline);
300 Script =
301 Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)[,]", @"$1$2" + val + "$3,",
302 RegexOptions.Compiled | RegexOptions.Multiline);
303 }
304
305 // Change jumps into goto's and prefix its label
306 Script =
307 Regex.Replace(Script,
308 @"(\W)jump\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*;",
309 @"$1goto label_$2;", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
310 // and prefix labels so the do not clash with C#'s reserved words
311 Script =
312 Regex.Replace(Script,
313 @"@([a-zA-Z_][a-zA-Z_0-9]*)\s*;",
314 @"label_$1: ;", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
315
316 // Add "void" in front of functions that needs it
317 Script =
318 Regex.Replace(Script,
319 @"^(\s*public\s+)?((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
320 @"$1void $2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
321
322 // Replace <x,y,z> and <x,y,z,r>
323 Script =
324 Regex.Replace(Script, @"<([^,>;]*,[^,>;]*,[^,>;]*,[^,>;]*)>", @"new LSL_Types.Quaternion($1)",
325 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
326 Script =
327 Regex.Replace(Script, @"<([^,>;)]*,[^,>;]*,[^,>;]*)>", @"new LSL_Types.Vector3($1)",
328 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
329
330 // Replace List []'s
331 Script =
332 Regex.Replace(Script, @"\[([^\]]*)\]", @"new LSL_Types.list($1)",
333 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
334
335 // Replace (string) to .ToString() //
336 Script =
337 Regex.Replace(Script, @"\(string\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.ToString()",
338 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
339 Script =
340 Regex.Replace(Script, @"\((float|int)\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.Parse($2)",
341 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
342
343 // Replace "state STATENAME" with "state("statename")"
344 Script =
345 Regex.Replace(Script, @"(state)\s+([^;\n\r]+)(;[\r\n\s])", "$1(\"$2\")$3",
346 RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
347
348 // REPLACE BACK QUOTES
349 foreach (string key in quotes.Keys)
350 {
351 string val;
352 quotes.TryGetValue(key, out val);
353 Script = Script.Replace(key, "\"" + val + "\"");
354 }
355
356 //System.Console.WriteLine(Script);
357 Return = String.Empty;// +
358 //"using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;";
359
360 //Return += String.Empty +
361 // "namespace SecondLife { ";
362 //Return += String.Empty +
363 // //"[Serializable] " +
364 // "public class Script : OpenSim.Region.ScriptEngine.Shared.LSL_BaseClass { ";
365 //Return += @"public Script() { } ";
366 Return += Script;
367 //Return += "} }\r\n";
368
369 quotes.Clear();
370
371 return Return;
372 }
373 }
374}
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index d6e6dae..c72d281 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -67,6 +67,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
67 private int m_SleepTime; 67 private int m_SleepTime;
68 private int m_SaveTime; 68 private int m_SaveTime;
69 private ThreadPriority m_Prio; 69 private ThreadPriority m_Prio;
70 private bool m_Enabled = true;
70 71
71// disable warning: need to keep a reference to XEngine.EventManager 72// disable warning: need to keep a reference to XEngine.EventManager
72// alive to avoid it being garbage collected 73// alive to avoid it being garbage collected
@@ -151,21 +152,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine
151 // 152 //
152 public void Initialise(Scene scene, IConfigSource configSource) 153 public void Initialise(Scene scene, IConfigSource configSource)
153 { 154 {
154 AppDomain.CurrentDomain.AssemblyResolve +=
155 OnAssemblyResolve;
156
157 m_log.InfoFormat("[XEngine] Initializing scripts in region {0}",
158 scene.RegionInfo.RegionName);
159 m_Scene = scene;
160
161 m_ScriptConfig = configSource.Configs["XEngine"]; 155 m_ScriptConfig = configSource.Configs["XEngine"];
162 156
163 if (m_ScriptConfig == null) 157 if (m_ScriptConfig == null)
164 { 158 {
165 m_log.ErrorFormat("[XEngine] No script configuration found. Scripts disabled"); 159// m_log.ErrorFormat("[XEngine] No script configuration found. Scripts disabled");
166 return; 160 return;
167 } 161 }
168 162
163 m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true);
164
165 if (!m_Enabled)
166 return;
167
168 AppDomain.CurrentDomain.AssemblyResolve +=
169 OnAssemblyResolve;
170
171 m_log.InfoFormat("[XEngine] Initializing scripts in region {0}",
172 scene.RegionInfo.RegionName);
173 m_Scene = scene;
174
169 m_MinThreads = m_ScriptConfig.GetInt("MinThreads", 2); 175 m_MinThreads = m_ScriptConfig.GetInt("MinThreads", 2);
170 m_MaxThreads = m_ScriptConfig.GetInt("MaxThreads", 100); 176 m_MaxThreads = m_ScriptConfig.GetInt("MaxThreads", 100);
171 m_IdleTimeout = m_ScriptConfig.GetInt("IdleTimeout", 60); 177 m_IdleTimeout = m_ScriptConfig.GetInt("IdleTimeout", 60);
@@ -220,6 +226,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
220 226
221 public void PostInitialise() 227 public void PostInitialise()
222 { 228 {
229 if (!m_Enabled)
230 return;
231
223 m_EventManager = new EventManager(this); 232 m_EventManager = new EventManager(this);
224 233
225 m_Compiler = new Compiler(this); 234 m_Compiler = new Compiler(this);
@@ -330,8 +339,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
330 get { return false; } 339 get { return false; }
331 } 340 }
332 341
333 public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez) 342 public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine)
334 { 343 {
344 if (engine != "XEngine")
345 return;
346
335 Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez}; 347 Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez};
336 348
337 lock (m_CompileQueue) 349 lock (m_CompileQueue)