Last active
July 18, 2022 15:54
-
-
Save SeargeDP/967f007ac896accfc214 to your computer and use it in GitHub Desktop.
Sandboxed scripting environment for C# based on Mono.CSharp for .NET 3.5 (works in Unity3D projects)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Written by Michael 'Searge' Stoyke in 03/2015 | |
// Released as public domain, do whatever you want with it! | |
using System; | |
using System.IO; | |
using System.Reflection; | |
using System.Text; | |
using Mono.CSharp; | |
namespace GameLibrary { | |
public class ScriptEngine { | |
private Evaluator _evaluator; | |
private StringBuilder _stringBuilder; | |
private ModuleContainer _module; | |
private ReflectionImporter _importer; | |
private MethodInfo _importTypes; | |
private string _error = string.Empty; | |
public ScriptEngine() { | |
_stringBuilder = new StringBuilder(); | |
TextWriter _writer = new StringWriter(_stringBuilder); | |
CompilerSettings settings = new CompilerSettings(); | |
settings.LoadDefaultReferences = false; | |
settings.StdLib = false; | |
ReportPrinter printer = new StreamReportPrinter(_writer); | |
CompilerContext ctx = new CompilerContext(settings, printer); | |
_evaluator = new Evaluator(ctx); | |
InitEvaluator(); | |
RegisterTypes(BuiltInTypes); | |
RegisterTypes(AdditionalTypes); | |
} | |
public bool Run(string code) { | |
_stringBuilder.Length = 0; | |
var result = _evaluator.Run(code); | |
_error = _stringBuilder.ToString(); | |
return result; | |
} | |
public bool Evaluate<T>(string code, out T result) { | |
object resultVal; | |
bool resultSet; | |
result = default(T); | |
_stringBuilder.Length = 0; | |
string res = _evaluator.Evaluate(code, out resultVal, out resultSet); | |
_error = _stringBuilder.ToString(); | |
if (res != null) { | |
return false; | |
} | |
if (resultSet) { | |
result = (T) resultVal; | |
} | |
return true; | |
} | |
public string GetLastError() { | |
return _error; | |
} | |
public void RegisterAssemblies(params Assembly[] apiAssembly) { | |
foreach (var assembly in apiAssembly) { | |
_evaluator.ReferenceAssembly(assembly); | |
} | |
} | |
public void RegisterTypes(params Type[] types) { | |
_importTypes.Invoke(_importer, new object[] { types, _module.GlobalRootNamespace, false }); | |
} | |
private void InitEvaluator() { | |
var fieldInfo1 = _evaluator.GetType().GetField("importer", BindingFlags.Instance | BindingFlags.NonPublic); | |
_importer = (ReflectionImporter)fieldInfo1.GetValue(_evaluator); | |
var fieldInfo2 = _evaluator.GetType().GetField("module", BindingFlags.Instance | BindingFlags.NonPublic); | |
_module = (ModuleContainer)fieldInfo2.GetValue(_evaluator); | |
_importTypes = _importer.GetType().GetMethod("ImportTypes", BindingFlags.NonPublic | BindingFlags.Instance, null, | |
CallingConventions.Any, new Type[] { typeof(Type[]), typeof(Namespace), typeof(bool) }, null); | |
} | |
private static Type[] BuiltInTypes { | |
get { | |
var types = new Type[] { | |
typeof (Object), typeof (ValueType), typeof (System.Attribute), typeof (Int32), | |
typeof (UInt32), typeof (Int64), typeof (UInt64), typeof (Single), | |
typeof (Double), typeof (Char), typeof (Int16), typeof (Decimal), | |
typeof (Boolean), typeof (SByte), typeof (Byte), typeof (UInt16), | |
typeof (String), typeof (System.Enum), typeof (System.Delegate), typeof (MulticastDelegate), | |
typeof (void), typeof (Array), typeof (Type), typeof (System.Collections.IEnumerator), | |
typeof (System.Collections.IEnumerable), typeof (IDisposable), typeof (IntPtr), typeof (UIntPtr), | |
typeof (RuntimeFieldHandle), typeof (RuntimeTypeHandle), typeof (Exception), typeof (ParamArrayAttribute), | |
typeof (System.Runtime.InteropServices.OutAttribute), | |
}; | |
return types; | |
} | |
} | |
private static Type[] AdditionalTypes { | |
get { | |
var types = new Type[] { | |
// mscorlib System | |
typeof (Action), | |
typeof (Action<>), | |
typeof (Action<,>), | |
typeof (Action<,,>), | |
typeof (Action<,,,>), | |
typeof (ArgumentException), | |
typeof (ArgumentNullException), | |
typeof (ArgumentOutOfRangeException), | |
typeof (ArithmeticException), | |
typeof (ArraySegment<>), | |
typeof (ArrayTypeMismatchException), | |
typeof (AsyncCallback), | |
typeof (BitConverter), | |
typeof (Buffer), | |
typeof (Comparison<>), | |
typeof (Convert), | |
typeof (Converter<,>), | |
typeof (DateTime), | |
typeof (DateTimeKind), | |
typeof (DateTimeOffset), | |
typeof (DayOfWeek), | |
typeof (DivideByZeroException), | |
typeof (EventArgs), | |
typeof (EventHandler), | |
typeof (EventHandler<>), | |
typeof (FlagsAttribute), | |
typeof (FormatException), | |
typeof (Func<>), | |
typeof (Func<,>), | |
typeof (Func<,,>), | |
typeof (Func<,,,>), | |
typeof (Func<,,,,>), | |
typeof (Guid), | |
typeof (IAsyncResult), | |
typeof (ICloneable), | |
typeof (IComparable), | |
typeof (IComparable<>), | |
typeof (IConvertible), | |
typeof (ICustomFormatter), | |
typeof (IEquatable<>), | |
typeof (IFormatProvider), | |
typeof (IFormattable), | |
typeof (IndexOutOfRangeException), | |
typeof (InvalidCastException), | |
typeof (InvalidOperationException), | |
typeof (InvalidTimeZoneException), | |
typeof (Math), | |
typeof (MidpointRounding), | |
typeof (NonSerializedAttribute), | |
typeof (NotFiniteNumberException), | |
typeof (NotImplementedException), | |
typeof (NotSupportedException), | |
typeof (Nullable), | |
typeof (Nullable<>), | |
typeof (NullReferenceException), | |
typeof (ObjectDisposedException), | |
typeof (ObsoleteAttribute), | |
typeof (OverflowException), | |
typeof (Predicate<>), | |
typeof (Random), | |
typeof (RankException), | |
typeof (SerializableAttribute), | |
typeof (StackOverflowException), | |
typeof (StringComparer), | |
typeof (StringComparison), | |
typeof (StringSplitOptions), | |
typeof (SystemException), | |
typeof (TimeoutException), | |
typeof (TimeSpan), | |
typeof (TimeZone), | |
typeof (TimeZoneInfo), | |
typeof (TimeZoneNotFoundException), | |
typeof (TypeCode), | |
typeof (Version), | |
typeof (WeakReference), | |
// mscorlib System.Collections | |
typeof (System.Collections.BitArray), | |
typeof (System.Collections.ICollection), | |
typeof (System.Collections.IComparer), | |
typeof (System.Collections.IDictionary), | |
typeof (System.Collections.IDictionaryEnumerator), | |
typeof (System.Collections.IEqualityComparer), | |
typeof (System.Collections.IList), | |
// mscorlib System.Collections.Generic | |
typeof (System.Collections.Generic.Comparer<>), | |
typeof (System.Collections.Generic.Dictionary<,>), | |
typeof (System.Collections.Generic.EqualityComparer<>), | |
typeof (System.Collections.Generic.ICollection<>), | |
typeof (System.Collections.Generic.IComparer<>), | |
typeof (System.Collections.Generic.IDictionary<,>), | |
typeof (System.Collections.Generic.IEnumerable<>), | |
typeof (System.Collections.Generic.IEnumerator<>), | |
typeof (System.Collections.Generic.IEqualityComparer<>), | |
typeof (System.Collections.Generic.IList<>), | |
typeof (System.Collections.Generic.KeyNotFoundException), | |
typeof (System.Collections.Generic.KeyValuePair<,>), | |
typeof (System.Collections.Generic.List<>), | |
// mscorlib System.Collections.ObjectModel | |
typeof (System.Collections.ObjectModel.Collection<>), | |
typeof (System.Collections.ObjectModel.KeyedCollection<,>), | |
typeof (System.Collections.ObjectModel.ReadOnlyCollection<>), | |
// mscorlib System.Globalization | |
typeof (System.Globalization.CharUnicodeInfo), | |
typeof (System.Globalization.CultureInfo), | |
typeof (System.Globalization.DateTimeFormatInfo), | |
typeof (System.Globalization.DateTimeStyles), | |
typeof (System.Globalization.NumberFormatInfo), | |
typeof (System.Globalization.NumberStyles), | |
typeof (System.Globalization.RegionInfo), | |
typeof (System.Globalization.StringInfo), | |
typeof (System.Globalization.TextElementEnumerator), | |
typeof (System.Globalization.TextInfo), | |
typeof (System.Globalization.UnicodeCategory), | |
// mscorlib System.IO | |
typeof (BinaryReader), | |
typeof (BinaryWriter), | |
typeof (BufferedStream), | |
typeof (EndOfStreamException), | |
typeof (FileAccess), | |
typeof (FileMode), | |
typeof (FileNotFoundException), | |
typeof (IOException), | |
typeof (MemoryStream), | |
typeof (Path), | |
typeof (PathTooLongException), | |
typeof (SeekOrigin), | |
typeof (Stream), | |
typeof (StringReader), | |
typeof (StringWriter), | |
typeof (TextReader), | |
typeof (TextWriter), | |
// mscorlib System.Text | |
typeof (ASCIIEncoding), | |
typeof (Decoder), | |
typeof (Encoder), | |
typeof (Encoding), | |
typeof (EncodingInfo), | |
typeof (StringBuilder), | |
typeof (UnicodeEncoding), | |
typeof (UTF32Encoding), | |
typeof (UTF7Encoding), | |
typeof (UTF8Encoding), | |
// System System.Collections.Generic | |
typeof (System.Collections.Generic.LinkedList<>), | |
typeof (System.Collections.Generic.LinkedListNode<>), | |
typeof (System.Collections.Generic.Queue<>), | |
typeof (System.Collections.Generic.SortedDictionary<,>), | |
typeof (System.Collections.Generic.SortedList<,>), | |
typeof (System.Collections.Generic.Stack<>), | |
// System System.Collections.Specialized | |
typeof (System.Collections.Specialized.BitVector32), | |
// System System.IO.Compression | |
typeof (System.IO.Compression.CompressionMode), | |
typeof (System.IO.Compression.DeflateStream), | |
typeof (System.IO.Compression.GZipStream), | |
// System System.Text.RegularExpressions | |
typeof (System.Text.RegularExpressions.Capture), | |
typeof (System.Text.RegularExpressions.CaptureCollection), | |
typeof (System.Text.RegularExpressions.Group), | |
typeof (System.Text.RegularExpressions.GroupCollection), | |
typeof (System.Text.RegularExpressions.Match), | |
typeof (System.Text.RegularExpressions.MatchCollection), | |
typeof (System.Text.RegularExpressions.MatchEvaluator), | |
typeof (System.Text.RegularExpressions.Regex), | |
typeof (System.Text.RegularExpressions.RegexCompilationInfo), | |
typeof (System.Text.RegularExpressions.RegexOptions), | |
// System.Core System.Collections.Generic | |
typeof (System.Collections.Generic.HashSet<>), | |
// System.Core System.Linq | |
typeof (System.Linq.Enumerable), | |
typeof (System.Linq.IGrouping<,>), | |
typeof (System.Linq.ILookup<,>), | |
typeof (System.Linq.IOrderedEnumerable<>), | |
typeof (System.Linq.IOrderedQueryable), | |
typeof (System.Linq.IOrderedQueryable<>), | |
typeof (System.Linq.IQueryable), | |
typeof (System.Linq.IQueryable<>), | |
typeof (System.Linq.IQueryProvider), | |
typeof (System.Linq.Lookup<,>), | |
typeof (System.Linq.Queryable), | |
}; | |
return types; | |
} | |
} | |
} | |
} |
Oops, didn't see your question earlier, Bill. If you are still looking for answers:
- If you look at the constructor, you'll see that the StringBuilder is used to pass error messages back from the sandbox.
- I don't have example code ready to share, but if I have a good example in the future, I'll post it here. Unfortunately I can't share the code that I use at the moment.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you are still willing to respond to questions about this code"
thanks, Bill.