diff options
author | Adam Frisby | 2009-03-05 00:52:59 +0000 |
---|---|---|
committer | Adam Frisby | 2009-03-05 00:52:59 +0000 |
commit | 65990de3905a4b117e5fef2c535fcc9d920be6c5 (patch) | |
tree | add357af0808eacceba0a389200836ec456850ae /OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs | |
parent | * Implements a number of members on SOGObject for use with the MRM Script Eng... (diff) | |
download | opensim-SC-65990de3905a4b117e5fef2c535fcc9d920be6c5.zip opensim-SC-65990de3905a4b117e5fef2c535fcc9d920be6c5.tar.gz opensim-SC-65990de3905a4b117e5fef2c535fcc9d920be6c5.tar.bz2 opensim-SC-65990de3905a4b117e5fef2c535fcc9d920be6c5.tar.xz |
MRM Scripting Changes
* Renames MiniRegionModule to MRMModule to make it more distinct from the actual Mini Region Module[s] executed in Scene.
* Renames MiniRegionModuleBase to MRMBase for convenience. MRM's need to be adjusted to inherit from MRMBase.
Diffstat (limited to 'OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs')
-rw-r--r-- | OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs new file mode 100644 index 0000000..86a3240 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs | |||
@@ -0,0 +1,235 @@ | |||
1 | using System; | ||
2 | using System.CodeDom.Compiler; | ||
3 | using System.Collections.Generic; | ||
4 | using System.IO; | ||
5 | using System.Reflection; | ||
6 | using System.Text; | ||
7 | using log4net; | ||
8 | using Microsoft.CSharp; | ||
9 | using Nini.Config; | ||
10 | using OpenMetaverse; | ||
11 | using OpenSim.Region.Framework.Interfaces; | ||
12 | using OpenSim.Region.Framework.Scenes; | ||
13 | |||
14 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
15 | { | ||
16 | public class MRMModule : IRegionModule | ||
17 | { | ||
18 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
19 | private Scene m_scene; | ||
20 | |||
21 | private readonly Dictionary<UUID,MRMBase> m_scripts = new Dictionary<UUID, MRMBase>(); | ||
22 | |||
23 | private static readonly CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); | ||
24 | |||
25 | public void Initialise(Scene scene, IConfigSource source) | ||
26 | { | ||
27 | if (source.Configs["MRM"] != null) | ||
28 | { | ||
29 | if (source.Configs["MRM"].GetBoolean("Enabled", false)) | ||
30 | { | ||
31 | m_log.Info("[MRM] Enabling MRM Module"); | ||
32 | m_scene = scene; | ||
33 | scene.EventManager.OnRezScript += EventManager_OnRezScript; | ||
34 | } | ||
35 | else | ||
36 | { | ||
37 | m_log.Info("[MRM] Disabled MRM Module (Express)"); | ||
38 | } | ||
39 | } | ||
40 | else | ||
41 | { | ||
42 | m_log.Info("[MRM] Disabled MRM Module (Omission)"); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) | ||
47 | { | ||
48 | if (script.StartsWith("//MiniMod:C#")) | ||
49 | { | ||
50 | m_log.Info("[MRM] Found C# MRM"); | ||
51 | IWorld m_world = new World(m_scene); | ||
52 | IHost m_host = new Host(new SOPObject(m_scene, localID)); | ||
53 | |||
54 | MRMBase mmb = (MRMBase) AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap( | ||
55 | CompileFromDotNetText(script, itemID.ToString()), | ||
56 | "OpenSim.MiniModule"); | ||
57 | m_log.Info("[MRM] Created MRM Instance"); | ||
58 | mmb.InitMiniModule(m_world, m_host); | ||
59 | m_scripts[itemID] = mmb; | ||
60 | |||
61 | m_log.Info("[MRM] Starting MRM"); | ||
62 | mmb.Start(); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | public void PostInitialise() | ||
67 | { | ||
68 | |||
69 | } | ||
70 | |||
71 | public void Close() | ||
72 | { | ||
73 | foreach (KeyValuePair<UUID, MRMBase> pair in m_scripts) | ||
74 | { | ||
75 | pair.Value.Stop(); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | public string Name | ||
80 | { | ||
81 | get { return "MiniRegionModule"; } | ||
82 | } | ||
83 | |||
84 | public bool IsSharedModule | ||
85 | { | ||
86 | get { return false; } | ||
87 | } | ||
88 | |||
89 | /// <summary> | ||
90 | /// Stolen from ScriptEngine Common | ||
91 | /// </summary> | ||
92 | /// <param name="Script"></param> | ||
93 | /// <param name="uuid">Unique ID for this module</param> | ||
94 | /// <returns></returns> | ||
95 | internal string CompileFromDotNetText(string Script, string uuid) | ||
96 | { | ||
97 | const string ext = ".cs"; | ||
98 | const string FilePrefix = "MiniModule"; | ||
99 | |||
100 | // Output assembly name | ||
101 | string OutFile = Path.Combine("MiniModules", Path.Combine( | ||
102 | m_scene.RegionInfo.RegionID.ToString(), | ||
103 | FilePrefix + "_compiled_" + uuid + ".dll")); | ||
104 | |||
105 | // Create Directories for Assemblies | ||
106 | if (!Directory.Exists("MiniModules")) | ||
107 | Directory.CreateDirectory("MiniModules"); | ||
108 | string tmp = Path.Combine("MiniModules", m_scene.RegionInfo.RegionID.ToString()); | ||
109 | if (!Directory.Exists(tmp)) | ||
110 | Directory.CreateDirectory(tmp); | ||
111 | |||
112 | try | ||
113 | { | ||
114 | File.Delete(OutFile); | ||
115 | } | ||
116 | catch (IOException e) | ||
117 | { | ||
118 | throw new Exception("Unable to delete old existing " + | ||
119 | "script-file before writing new. Compile aborted: " + | ||
120 | e); | ||
121 | } | ||
122 | |||
123 | // DEBUG - write source to disk | ||
124 | string srcFileName = FilePrefix + "_source_" + | ||
125 | Path.GetFileNameWithoutExtension(OutFile) + ext; | ||
126 | try | ||
127 | { | ||
128 | File.WriteAllText(Path.Combine(Path.Combine( | ||
129 | "MiniModules", | ||
130 | m_scene.RegionInfo.RegionID.ToString()), | ||
131 | srcFileName), Script); | ||
132 | } | ||
133 | catch (Exception ex) //NOTLEGIT - Should be just FileIOException | ||
134 | { | ||
135 | m_log.Error("[Compiler]: Exception while " + | ||
136 | "trying to write script source to file \"" + | ||
137 | srcFileName + "\": " + ex.ToString()); | ||
138 | } | ||
139 | |||
140 | // Do actual compile | ||
141 | CompilerParameters parameters = new CompilerParameters(); | ||
142 | |||
143 | parameters.IncludeDebugInformation = true; | ||
144 | |||
145 | string rootPath = | ||
146 | Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); | ||
147 | |||
148 | |||
149 | // TODO: Add Libraries | ||
150 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | ||
151 | "OpenSim.Region.OptionalModules.dll")); | ||
152 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | ||
153 | "log4net.dll")); | ||
154 | |||
155 | parameters.GenerateExecutable = false; | ||
156 | parameters.OutputAssembly = OutFile; | ||
157 | parameters.IncludeDebugInformation = true; | ||
158 | parameters.TreatWarningsAsErrors = false; | ||
159 | |||
160 | CompilerResults results = CScodeProvider.CompileAssemblyFromSource( | ||
161 | parameters, Script); | ||
162 | |||
163 | int display = 5; | ||
164 | if (results.Errors.Count > 0) | ||
165 | { | ||
166 | string errtext = String.Empty; | ||
167 | foreach (CompilerError CompErr in results.Errors) | ||
168 | { | ||
169 | // Show 5 errors max | ||
170 | // | ||
171 | if (display <= 0) | ||
172 | break; | ||
173 | display--; | ||
174 | |||
175 | string severity = "Error"; | ||
176 | if (CompErr.IsWarning) | ||
177 | { | ||
178 | severity = "Warning"; | ||
179 | } | ||
180 | |||
181 | string text = CompErr.ErrorText; | ||
182 | |||
183 | // The Second Life viewer's script editor begins | ||
184 | // countingn lines and columns at 0, so we subtract 1. | ||
185 | errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n", | ||
186 | CompErr.Line - 1, CompErr.Column - 1, | ||
187 | CompErr.ErrorNumber, text, severity); | ||
188 | } | ||
189 | |||
190 | if (!File.Exists(OutFile)) | ||
191 | { | ||
192 | throw new Exception(errtext); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | if (!File.Exists(OutFile)) | ||
197 | { | ||
198 | string errtext = String.Empty; | ||
199 | errtext += "No compile error. But not able to locate compiled file."; | ||
200 | throw new Exception(errtext); | ||
201 | } | ||
202 | |||
203 | FileInfo fi = new FileInfo(OutFile); | ||
204 | |||
205 | Byte[] data = new Byte[fi.Length]; | ||
206 | |||
207 | try | ||
208 | { | ||
209 | FileStream fs = File.Open(OutFile, FileMode.Open, FileAccess.Read); | ||
210 | fs.Read(data, 0, data.Length); | ||
211 | fs.Close(); | ||
212 | } | ||
213 | catch (IOException) | ||
214 | { | ||
215 | string errtext = String.Empty; | ||
216 | errtext += "No compile error. But not able to open file."; | ||
217 | throw new Exception(errtext); | ||
218 | } | ||
219 | |||
220 | // Convert to base64 | ||
221 | // | ||
222 | string filetext = Convert.ToBase64String(data); | ||
223 | |||
224 | ASCIIEncoding enc = new ASCIIEncoding(); | ||
225 | |||
226 | Byte[] buf = enc.GetBytes(filetext); | ||
227 | |||
228 | FileStream sfs = File.Create(OutFile + ".cil.b64"); | ||
229 | sfs.Write(buf, 0, buf.Length); | ||
230 | sfs.Close(); | ||
231 | |||
232 | return OutFile; | ||
233 | } | ||
234 | } | ||
235 | } | ||