internal static string Execute(string content, CmdContext msg) { using (NLua.Lua lua = new NLua.Lua()) using (PrintProxy proxy = new PrintProxy()) { lua.RegisterFunction("print", proxy, proxy.GetType().GetMethod("Print", new Type[] { typeof(object[]) })); string code; using (StreamReader sr = new StreamReader(typeof(Lua).Assembly.GetManifestResourceStream("DuckBot.Resources.Sandbox.lua"))) code = sr.ReadToEnd(); try { const string template = "args = {...};rawText,sender,server,channel=args[1],args[2],args[3],args[4]\n"; string source = template + content; using (LuaFunction func = (LuaFunction)lua.DoString(code, "sandbox")[0]) { object[] rets = func.Call(source, msg.Args, msg.Sender, msg.Server, msg.Channel); if (rets.Length >= 2) { object[] arr = new object[rets.Length - 1]; Array.Copy(rets, 1, arr, 0, arr.Length); proxy.Print(arr); } string res = proxy.ToString().Trim(); return(res.Length == 0 ? msg.GetString("Strings.ret_empty_script") : res); } } catch (NLua.Exceptions.LuaScriptException ex) { return(msg.GetString("err_generic") + ": " + ex.Message + "\n``` " + ex.Source + " ```"); } } }
private static string Compile(string content, CmdContext msg) { const string template = "using System;using System.Net;using System.Collections.Generic;using Discord;namespace DuckBot {public static class Script {public static string Code(string rawText,dynamic sender,dynamic server,dynamic channel){\n"; string source = template + content + "}}}"; using (CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp")) { Assembly ass = typeof(Program).Assembly; CompilerParameters pars = new CompilerParameters(); foreach (AssemblyName an in ass.GetReferencedAssemblies()) { pars.ReferencedAssemblies.Add(Assembly.ReflectionOnlyLoad(an.FullName).Location); } pars.ReferencedAssemblies.Add(ass.Location); pars.GenerateExecutable = false; pars.GenerateInMemory = false; pars.OutputAssembly = Guid.NewGuid() + ".dll"; CompilerResults results = compiler.CompileAssemblyFromSource(pars, source); if (!results.Errors.HasErrors) { return(Path.GetFullPath(pars.OutputAssembly)); } else { StringBuilder errors = new StringBuilder(msg.GetString("err_compile") + ": "); errors.AppendFormat("{0},{1}: ``` {2} ```", results.Errors[0].Line - 1, results.Errors[0].Column, results.Errors[0].ErrorText); throw new FormatException(errors.ToString()); } } }
internal static string Execute(string content, CmdContext msg) { AppDomainSetup setup = new AppDomainSetup() { ApplicationBase = AppDomain.CurrentDomain.BaseDirectory, DisallowBindingRedirects = true, DisallowCodeDownload = true, DisallowPublisherPolicy = true }; PermissionSet ps = new PermissionSet(PermissionState.None); ps.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, setup.ApplicationBase)); ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution | SecurityPermissionFlag.UnmanagedCode | SecurityPermissionFlag.ControlThread)); ps.AddPermission(new System.Net.WebPermission(PermissionState.Unrestricted)); AppDomain app = null; string dll = null; try { dll = Compile(content, msg); app = AppDomain.CreateDomain(dll, null, setup, ps); CS obj = (CS)app.CreateInstanceAndUnwrap(typeof(CS).Assembly.FullName, typeof(CS).FullName); using (StringWriter sw = new StringWriter()) { try { sw.WriteLine(obj.Remote(CultureInfo.CurrentCulture, sw, dll, msg.Args, Proxy.GetProxy(msg.Sender), Proxy.GetProxy(msg.Server), Proxy.GetProxy(msg.Channel))); } catch (TargetInvocationException) { return(msg.GetString("err_scrtimeout")); } string res = sw.ToString().Trim(); return(res.Length == 0 ? msg.GetString("ret_empty_script") : res); } } catch (FormatException ex) { return(ex.Message); } finally { if (app != null) { AppDomain.Unload(app); } if (dll != null) { File.Delete(dll); } } }