void Client_OnQueryMessage(object sender, IrcEventArgs e) { using (var context = new DataContext()) { switch (e.Data.Type) { case ReceiveType.Join: Client.RfcNotice(e.Data.Nick, "Hi, I am a IRC bot written in C# that executes code with Roslyn."); Client.RfcNotice(e.Data.Nick, "To try me out, send me a private message with the following: var hello = \"hello world\"; return hello;"); Client.RfcNotice(e.Data.Nick, "You can also execute multi-line commands by starting the line with \">>\" remember to have a return statement in your last command"); break; case ReceiveType.ChannelMessage: if ((e.Data.Type == ReceiveType.ChannelMessage && e.Data.Message.StartsWith(BotSettings.Default.Name) && e.Data.Message.Length > BotSettings.Default.Name.Length) || (e.Data.Message.StartsWith(">>") && e.Data.Message.Length > 4)) { var queryCommand = e.Data.Message.Substring(string.Format(BotSettings.Default.Name).Length + 1).Trim(); ProcessCommand(e, context, queryCommand); } break; case ReceiveType.QueryMessage: var channelCommand = e.Data.Message; ProcessCommand(e, context, channelCommand); break; } } }
public object Execute(string code) { Thread.CurrentThread.CurrentCulture = new CultureInfo("en"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("en"); // if (!Validate(code)) return "Not implemented"; const string entryPoint = "using System; public class EntryPoint { public static object Result {get;set;} public static void Main() { try { Result = Script.Eval(); } catch(Exception ex) { Result = ex.ToString(); } } }"; // new StreamReader("EntryPoint.txt").ReadToEnd(); var script = "public static object Eval() {" + code + "}"; var core = Assembly.Load("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); var system = Assembly.Load("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); string[] namespaces; using (var context = new DataContext()) { var query = from ns in context.Namespaces select ns.Namespace; namespaces = query.ToArray(); } var compilation = Compilation.Create("foo", options: new CompilationOptions(assemblyKind: AssemblyKind.ConsoleApplication, usings: ReadOnlyArray<string>.CreateFrom(namespaces)), syntaxTrees: new[] { SyntaxTree.ParseCompilationUnit(entryPoint), SyntaxTree.ParseCompilationUnit(script, options: new ParseOptions(kind: SourceCodeKind.Interactive)) }, references: new MetadataReference[] { new AssemblyFileReference(typeof(object).Assembly.Location), new AssemblyFileReference(core.Location), new AssemblyFileReference(system.Location) }); byte[] compiledAssembly; using (var output = new MemoryStream()) { EmitResult emitResult = compilation.Emit(output, null, null, null, xmlNameResolver: null); if (!emitResult.Success) { var errors = emitResult.Diagnostics.Select(x => x.Info.GetMessage().Replace("Eval()", "<Factory>()").ToString()).ToArray(); return String.Join(", ", errors); } // report errors if emitResult.Diagnostics has any compiledAssembly = output.ToArray(); } if (compiledAssembly.Length == 0) return "Incorrect data"; AppDomain sandbox = CreateSandbox(); var loader = (ByteCodeLoader)Activator.CreateInstance(sandbox, typeof(ByteCodeLoader).Assembly.FullName, typeof(ByteCodeLoader).FullName).Unwrap(); object result = null; try { var scriptThread = new Thread(() => { Thread.CurrentThread.CurrentCulture = new CultureInfo("en"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("en"); try { result = loader.Run(compiledAssembly); } catch(Exception ex) { result = ex.Message; } }); scriptThread.Start(); if (!scriptThread.Join(6000)) { scriptThread.Abort(); AppDomain.Unload(sandbox); return "Timeout"; } } catch(Exception ex) { result = ex.InnerException != null ? ex.InnerException.ToString() : ex.ToString(); } AppDomain.Unload(sandbox); if (result == null || String.IsNullOrEmpty(result.ToString())) result = "null"; return FormatResult(result); }
void Execute(IrcEventArgs e, DataContext context, string commandText) { if (context.Commands.Any(x => x.Username == e.Data.Nick)) { var commands = context.Commands.Where(x => x.Username == e.Data.Nick).OrderBy(x => x.Posted).Select(x => x.Command).ToArray(); var toExecute = string.Join(Environment.NewLine, commands); toExecute += commandText; RunInSandbox(toExecute, e.Data); foreach (var command in context.Commands.Where(x => x.Username == e.Data.Nick)) context.DeleteObject(command); context.SaveChanges(); } else { RunInSandbox(commandText, e.Data); } }
void QueueCommand(IrcEventArgs e, DataContext context, string commandText) { commandText = commandText.Substring(2).Trim(); var command = new Commands { Id = Guid.NewGuid(), Command = commandText.Trim(), Posted = DateTime.Now, Username = e.Data.Nick }; context.Commands.AddObject(command); context.SaveChanges(); }
void ProcessCommand(IrcEventArgs e, DataContext context, string commandText) { if (context.Users.Any(x => x.Ident == e.Data.Ident && x.UserLevel == -1)) return; if (IsPasteUrl(commandText.Split(' ')[0])) { HandlePastedCode(e, context, commandText); } else if (commandText.StartsWith(">>")) { QueueCommand(e, context, commandText); } else { Execute(e, context, commandText); } }
void HandlePastedCode(IrcEventArgs e, DataContext context, string commandText) { var host = commandText.Split(' ')[0]; var client = new WebClient(); string pasteId = string.Empty; string toExecute = string.Empty; if (host.Contains("http://pastebin.com")) { pasteId = commandText.Split(' ')[0].Replace("http://pastebin.com/", ""); toExecute = client.DownloadString(string.Format("http://pastebin.com/raw.php?i={0}", pasteId)); } else if (host.Contains("http://pastie.org")) { pasteId = commandText.Split(' ')[0].Replace("http://pastie.org/", ""); toExecute = client.DownloadString(string.Format("http://pastie.org/pastes/{0}/text", pasteId)); } Execute(e, context, toExecute); }