aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Scripting/Minimodule/MiniModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Scripting/Minimodule/MiniModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/MiniModule.cs202
1 files changed, 202 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MiniModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MiniModule.cs
new file mode 100644
index 0000000..eb98215
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MiniModule.cs
@@ -0,0 +1,202 @@
1using System;
2using System.CodeDom.Compiler;
3using System.IO;
4using System.Reflection;
5using System.Text;
6using log4net;
7using Microsoft.CSharp;
8using Nini.Config;
9using OpenSim.Region.Framework.Interfaces;
10using OpenSim.Region.Framework.Scenes;
11
12namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
13{
14 class MiniModule : IRegionModule
15 {
16 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
17 private Scene m_scene;
18
19
20 private static readonly CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
21
22 public void Initialise(Scene scene, IConfigSource source)
23 {
24 m_scene = scene;
25 scene.EventManager.OnRezScript += EventManager_OnRezScript;
26 }
27
28 void EventManager_OnRezScript(uint localID, OpenMetaverse.UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource)
29 {
30 if(engine == "MiniMod")
31 {
32 if(script.StartsWith("//MiniMod:C#"))
33 {
34 IWorld m_world = new World(m_scene);
35 IHost m_host = new Host(new SOPObject(m_scene, localID));
36
37 MiniModuleBase mmb = (MiniModuleBase) AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap(
38 CompileFromDotNetText(script, itemID.ToString()),
39 "OpenSim.MiniModule");
40 mmb.InitMiniModule(m_world, m_host);
41 }
42 }
43 }
44
45 public void PostInitialise()
46 {
47
48 }
49
50 public void Close()
51 {
52
53 }
54
55 public string Name
56 {
57 get { return "MiniScriptModule"; }
58 }
59
60 public bool IsSharedModule
61 {
62 get { return false; }
63 }
64
65 /// <summary>
66 /// Stolen from ScriptEngine Common
67 /// </summary>
68 /// <param name="Script"></param>
69 /// <param name="uuid">Unique ID for this module</param>
70 /// <returns></returns>
71 internal string CompileFromDotNetText(string Script, string uuid)
72 {
73 const string ext = ".cs";
74 const string FilePrefix = "MiniModule";
75
76 // Output assembly name
77 string OutFile = Path.Combine("MiniModules", Path.Combine(
78 m_scene.RegionInfo.RegionID.ToString(),
79 FilePrefix + "_compiled_" + uuid + ".dll"));
80 try
81 {
82 File.Delete(OutFile);
83 }
84 catch (IOException e)
85 {
86 throw new Exception("Unable to delete old existing " +
87 "script-file before writing new. Compile aborted: " +
88 e);
89 }
90
91 // DEBUG - write source to disk
92 string srcFileName = FilePrefix + "_source_" +
93 Path.GetFileNameWithoutExtension(OutFile) + ext;
94 try
95 {
96 File.WriteAllText(Path.Combine(Path.Combine(
97 "MiniModules",
98 m_scene.RegionInfo.RegionID.ToString()),
99 srcFileName), Script);
100 }
101 catch (Exception ex) //NOTLEGIT - Should be just FileIOException
102 {
103 m_log.Error("[Compiler]: Exception while " +
104 "trying to write script source to file \"" +
105 srcFileName + "\": " + ex.ToString());
106 }
107
108 // Do actual compile
109 CompilerParameters parameters = new CompilerParameters();
110
111 parameters.IncludeDebugInformation = true;
112
113 string rootPath =
114 Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
115
116
117 // TODO: Add Libraries
118 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
119 "OpenSim.Region.OptionalModules.dll"));
120
121
122 parameters.GenerateExecutable = false;
123 parameters.OutputAssembly = OutFile;
124 parameters.IncludeDebugInformation = true;
125 parameters.TreatWarningsAsErrors = false;
126
127 CompilerResults results = CScodeProvider.CompileAssemblyFromSource(
128 parameters, Script);
129
130 int display = 5;
131 if (results.Errors.Count > 0)
132 {
133 string errtext = String.Empty;
134 foreach (CompilerError CompErr in results.Errors)
135 {
136 // Show 5 errors max
137 //
138 if (display <= 0)
139 break;
140 display--;
141
142 string severity = "Error";
143 if (CompErr.IsWarning)
144 {
145 severity = "Warning";
146 }
147
148 string text = CompErr.ErrorText;
149
150 // The Second Life viewer's script editor begins
151 // countingn lines and columns at 0, so we subtract 1.
152 errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n",
153 CompErr.Line - 1, CompErr.Column - 1,
154 CompErr.ErrorNumber, text, severity);
155 }
156
157 if (!File.Exists(OutFile))
158 {
159 throw new Exception(errtext);
160 }
161 }
162
163 if (!File.Exists(OutFile))
164 {
165 string errtext = String.Empty;
166 errtext += "No compile error. But not able to locate compiled file.";
167 throw new Exception(errtext);
168 }
169
170 FileInfo fi = new FileInfo(OutFile);
171
172 Byte[] data = new Byte[fi.Length];
173
174 try
175 {
176 FileStream fs = File.Open(OutFile, FileMode.Open, FileAccess.Read);
177 fs.Read(data, 0, data.Length);
178 fs.Close();
179 }
180 catch (IOException)
181 {
182 string errtext = String.Empty;
183 errtext += "No compile error. But not able to open file.";
184 throw new Exception(errtext);
185 }
186
187 // Convert to base64
188 //
189 string filetext = Convert.ToBase64String(data);
190
191 ASCIIEncoding enc = new ASCIIEncoding();
192
193 Byte[] buf = enc.GetBytes(filetext);
194
195 FileStream sfs = File.Create(OutFile + ".cil.b64");
196 sfs.Write(buf, 0, buf.Length);
197 sfs.Close();
198
199 return OutFile;
200 }
201 }
202}