private void OnMessage(ObjectStreamConnection<CompilerMessage, CompilerMessage> connection, CompilerMessage message) { if (message == null) { Interface.Oxide.NextTick(() => { OnCompilerFailed("Compiler disconnected."); Shutdown(); }); return; } switch (message.Type) { case CompilerMessageType.Assembly: var compilation = compilations[message.Id]; if (compilation == null) { Interface.Oxide.LogWarning("CSharp compiler compiled an unknown assembly!"); return; } compilation.endedAt = Interface.Oxide.Now; var stdOutput = (string)message.ExtraData; if (stdOutput != null) { foreach (var line in stdOutput.Split('\r', '\n')) { var match = fileErrorRegex.Match(line.Trim()); for (var i = 1; i < match.Groups.Count; i++) { var value = match.Groups[i].Value; if (value.Trim() == string.Empty) continue; var file_name = value.Basename(); var script_name = file_name.Substring(0, file_name.Length - 3); var compilable_plugin = compilation.plugins.SingleOrDefault(pl => pl.ScriptName == script_name); if (compilable_plugin == null) { Interface.Oxide.LogError("Unable to resolve script error to plugin: " + line); continue; } var missing_requirements = compilable_plugin.Requires.Where(name => !compilation.IncludesRequiredPlugin(name)); if (missing_requirements.Any()) compilable_plugin.CompilerErrors = $"Missing dependencies: {missing_requirements.ToSentence()}"; else compilable_plugin.CompilerErrors = line.Trim().Replace(Interface.Oxide.PluginDirectory + Path.DirectorySeparatorChar, string.Empty); } } } compilation.Completed((byte[])message.Data); compilations.Remove(message.Id); idleTimer?.Destroy(); if (AutoShutdown) { Interface.Oxide.NextTick(() => { idleTimer?.Destroy(); if (AutoShutdown) idleTimer = Interface.Oxide.GetLibrary<Core.Libraries.Timer>().Once(60, Shutdown); }); } break; case CompilerMessageType.Error: Interface.Oxide.LogError("Compilation error: {0}", message.Data); compilations[message.Id].Completed(); compilations.Remove(message.Id); idleTimer?.Destroy(); if (AutoShutdown) { Interface.Oxide.NextTick(() => { idleTimer?.Destroy(); idleTimer = Interface.Oxide.GetLibrary<Core.Libraries.Timer>().Once(60, Shutdown); }); } break; case CompilerMessageType.Ready: connection.PushMessage(message); if (!ready) { ready = true; while (messageQueue.Count > 0) connection.PushMessage(messageQueue.Dequeue()); } break; } }
private void EnqueueCompilation(Compilation compilation) { if (compilation.plugins.Count < 1) { Interface.Oxide.LogDebug("EnqueueCompilation called for an empty compilation"); return; } if (!CheckCompiler()) { OnCompilerFailed("Compiler couldn't be started."); return; } compilation.Started(); //Interface.Oxide.LogDebug("Compiling with references: " + compilation.references.Keys.ToSentence()); var source_files = compilation.plugins.SelectMany(plugin => plugin.IncludePaths).Distinct().Select(path => new CompilerFile(path)).ToList(); source_files.AddRange(compilation.plugins.Select(plugin => new CompilerFile(plugin.ScriptName + ".cs", plugin.ScriptSource))); //Interface.Oxide.LogDebug("Compiling files: " + source_files.Select(f => f.Name).ToSentence()); var data = new CompilerData { OutputFile = compilation.name, SourceFiles = source_files.ToArray(), ReferenceFiles = compilation.references.Values.ToArray() }; var message = new CompilerMessage { Id = compilation.id, Data = data, Type = CompilerMessageType.Compile }; if (ready) client.PushMessage(message); else messageQueue.Enqueue(message); }
private void SpawnCompiler(int currentId) { var compilation = pluginComp[currentId]; compilation.startedAt = Interface.Oxide.Now; var referenceFiles = new List<CompilerFile>(compilation.references.Count); referenceFiles.AddRange(compilation.references.Select(reference_name => new CompilerFile { Name = reference_name + ".dll", Data = File.ReadAllBytes(Path.Combine(Interface.Oxide.ExtensionDirectory, reference_name + ".dll")) })); var sourceFiles = compilation.plugins.SelectMany(plugin => plugin.IncludePaths).Distinct().Select(includePath => new CompilerFile { Name = Path.GetFileName(includePath), Data = File.ReadAllBytes(includePath) }).ToList(); sourceFiles.AddRange(compilation.plugins.Select(plugin => new CompilerFile { Name = plugin.ScriptName + ".cs", Data = plugin.ScriptEncoding.GetBytes(string.Join(Environment.NewLine, plugin.ScriptLines)) })); var compilerData = new CompilerData { OutputFile = (compilation.plugins.Count == 1 ? compilation.plugins[0].Name : "plugins_") + Math.Round(Interface.Oxide.Now * 10000000f) + ".dll", SourceFiles = sourceFiles.ToArray(), ReferenceFiles = referenceFiles.ToArray() }; var message = new CompilerMessage {Id = currentId, Data = compilerData, Type = CompilerMessageType.Compile}; if (ready) client.PushMessage(message); else compQueue.Enqueue(message); }
private void SpawnCompiler(int currentId) { var compilation = pluginComp[currentId]; compilation.Started(); var source_files = compilation.plugins.SelectMany(plugin => plugin.IncludePaths).Distinct().Select(path => new CompilerFile(path)).ToList(); source_files.AddRange(compilation.plugins.Select(plugin => new CompilerFile(plugin.ScriptName + ".cs", plugin.ScriptSource))); var compilerData = new CompilerData { OutputFile = compilation.name, SourceFiles = source_files.ToArray(), ReferenceFiles = compilation.references.ToArray() }; var message = new CompilerMessage { Id = currentId, Data = compilerData, Type = CompilerMessageType.Compile }; if (ready) client.PushMessage(message); else compQueue.Enqueue(message); }
private void OnMessage(ObjectStreamConnection<CompilerMessage, CompilerMessage> connection, CompilerMessage message) { if (message == null) { Interface.Oxide.NextTick(OnShutdown); return; } switch (message.Type) { case CompilerMessageType.Assembly: var compilation = pluginComp[message.Id]; compilation.endedAt = Interface.Oxide.Now; var stdOutput = (string)message.ExtraData; if (stdOutput != null) { foreach (var line in stdOutput.Split('\r', '\n')) { var match = fileErrorRegex.Match(line.Trim()); for (var i = 1; i < match.Groups.Count; i++) { var value = match.Groups[i].Value; if (value.Trim() == string.Empty) continue; var file_name = value.Basename(); var script_name = file_name.Substring(0, file_name.Length - 3); var compilable_plugin = compilation.plugins.SingleOrDefault(pl => pl.ScriptName == script_name); if (compilable_plugin == null) { Interface.Oxide.LogError("Unable to resolve script error to plugin: " + line); continue; } var missing_requirements = compilable_plugin.Requires.Where(name => compilation.plugins.Single(pl => pl.Name == name).CompilerErrors != null).ToArray(); if (missing_requirements.Length > 0) compilable_plugin.CompilerErrors = $"{compilable_plugin.ScriptName}'s dependencies: {missing_requirements.ToSentence()}"; else compilable_plugin.CompilerErrors = line.Trim().Replace(Interface.Oxide.PluginDirectory + "\\", string.Empty); } } } Interface.Oxide.NextTick(() => compilation.callback((byte[])message.Data, compilation.Duration)); pluginComp.Remove(message.Id); idleTimer?.Destroy(); idleTimer = Interface.Oxide.GetLibrary<Core.Libraries.Timer>().Once(60, OnShutdown); break; case CompilerMessageType.Error: Interface.Oxide.LogError("Compilation error: {0}", message.Data); var comp = pluginComp[message.Id]; Interface.Oxide.NextTick(() => comp.callback(null, 0)); pluginComp.Remove(message.Id); idleTimer?.Destroy(); idleTimer = Interface.Oxide.GetLibrary<Core.Libraries.Timer>().Once(60, OnShutdown); break; case CompilerMessageType.Ready: connection.PushMessage(message); if (!ready) { ready = true; while (compQueue.Count > 0) connection.PushMessage(compQueue.Dequeue()); } break; } }