Skip to content

Commit

Permalink
Custom commands GUI compiling now generates temp .dll path itself, in…
Browse files Browse the repository at this point in the history
…stead of relying on CodeDomCompiler to generate it through 'GenerateInMemory'
  • Loading branch information
UnknownShadow200 committed Jul 22, 2022
1 parent d182a3c commit 5d8289d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 40 deletions.
71 changes: 42 additions & 29 deletions GUI/Popups/CustomCommands.cs
Expand Up @@ -81,7 +81,6 @@ public partial class CustomCommands : Form {
}

void btnLoad_Click(object sender, EventArgs e) {
Assembly lib;
string path;

using (FileDialog dialog = new OpenFileDialog()) {
Expand All @@ -94,13 +93,14 @@ public partial class CustomCommands : Form {
if (!File.Exists(path)) return;

if (path.CaselessEnds(".dll")) {
lib = IScripting.LoadAssembly(path);
} else {
lib = CompileCommands(path);
LoadCommands(path); return;
}

if (lib == null) return;
LoadCommands(lib);

// compile to temp .dll and load that
string tmp = CompileCommands(path);
if (tmp == null) return;
LoadCommands(tmp);
DeleteAssembly(tmp);
}

void btnUnload_Click(object sender, EventArgs e) {
Expand All @@ -120,42 +120,55 @@ public partial class CustomCommands : Form {
}


static ICompiler GetCompiler(string path) {
foreach (ICompiler c in ICompiler.Compilers) {
if (path.CaselessEnds(c.FileExtension)) return c;
void LoadCommands(string path) {
Assembly lib = IScripting.LoadAssembly(path);
if (lib == null) return;
List<Command> commands = IScripting.LoadTypes<Command>(lib);

for (int i = 0; i < commands.Count; i++)
{
Command cmd = commands[i];

if (lstCommands.Items.Contains(cmd.name)) {
Popup.Warning("Command " + cmd.name + " already exists, so was not loaded");
continue;
}

lstCommands.Items.Add(cmd.name);
Command.Register(cmd);
Logger.Log(LogType.SystemActivity, "Added /" + cmd.name + " to commands");
}
return null;
}

Assembly CompileCommands(string path) {
string CompileCommands(string path) {
ICompiler compiler = GetCompiler(path);
if (compiler == null) {
Popup.Warning("Unsupported file '" + path + "'");
return null;
}

}
string tmp = "extra/commands/" + Path.GetRandomFileName() + ".dll";

ConsoleHelpPlayer p = new ConsoleHelpPlayer();
CompilerResults result = CompilerOperations.Compile(p, compiler, "Command", new[] { path }, null);
if (result != null) return result.CompiledAssembly;
CompilerResults result = CompilerOperations.Compile(p, compiler, "Command", new[] { path }, tmp);
if (result != null && !result.Errors.HasErrors) return tmp;

Popup.Error(Colors.StripUsed(p.Messages));
DeleteAssembly(tmp);
return null;
}

void LoadCommands(Assembly assembly) {
List<Command> commands = IScripting.LoadTypes<Command>(assembly);
for (int i = 0; i < commands.Count; i++) {
Command cmd = commands[i];

if (lstCommands.Items.Contains(cmd.name)) {
Popup.Warning("Command " + cmd.name + " already exists, so was not loaded");
continue;
}

lstCommands.Items.Add(cmd.name);
Command.Register(cmd);
Logger.Log(LogType.SystemActivity, "Added " + cmd.name + " to commands");
static ICompiler GetCompiler(string path) {
foreach (ICompiler c in ICompiler.Compilers)
{
if (path.CaselessEnds(c.FileExtension)) return c;
}
return null;
}

static void DeleteAssembly(string path) {
try { File.Delete(path); } catch { }
try { File.Delete(path.Replace(".dll", ".pdb")); } catch { }
try { File.Delete(path + ".mdb"); } catch { }
}


Expand Down
15 changes: 5 additions & 10 deletions MCGalaxy/Modules/Compiling/Compiler.cs
Expand Up @@ -37,7 +37,7 @@ public abstract class ICompiler
/// <example> .cs, .vb </example>
public abstract string FileExtension { get; }
/// <summary> The short name of this programming language </summary>
/// <example> CS, VB </example>
/// <example> C#, VB </example>
public abstract string ShortName { get; }
/// <summary> The full name of this programming language </summary>
/// <example> CSharp, Visual Basic </example>
Expand All @@ -46,6 +46,9 @@ public abstract class ICompiler
public abstract string CommandSkeleton { get; }
/// <summary> Returns source code for an example Plugin </summary>
public abstract string PluginSkeleton { get; }
/// <summary> Returns the starting characters for a comment </summary>
/// <example> For C# this is "//" </example>
protected virtual string CommentPrefix { get { return "//"; } }

public string CommandPath(string name) { return COMMANDS_SOURCE_DIR + "Cmd" + name + FileExtension; }
public string PluginPath(string name) { return PLUGINS_SOURCE_DIR + name + FileExtension; }
Expand Down Expand Up @@ -76,16 +79,13 @@ public abstract class ICompiler
}


const int maxLog = 2;
/// <summary> Attempts to compile the given source code file to a .dll file. </summary>
/// <remarks> If dstPath is null, compiles to an in-memory .dll instead. </remarks>
/// <remarks> Logs errors to IScripting.ErrorPath. </remarks>
public CompilerResults Compile(string srcPath, string dstPath) {
return Compile(new [] { srcPath }, dstPath);
}

/// <summary> Attempts to compile the given source code files to a .dll file. </summary>
/// <remarks> If dstPath is null, compiles to an in-memory .dll instead. </remarks>
/// <remarks> Logs errors to IScripting.ErrorPath. </remarks>
public CompilerResults Compile(string[] srcPaths, string dstPath) {
CompilerResults results = DoCompile(srcPaths, dstPath);
Expand Down Expand Up @@ -142,9 +142,6 @@ public abstract class ICodeDomCompiler : ICompiler
protected abstract CodeDomProvider CreateProvider();
/// <summary> Adds language-specific default arguments to list of arguments. </summary>
protected abstract void PrepareArgs(CompilerParameters args);
/// <summary> Returns the starting characters for a comment </summary>
/// <example> For C# this is "//" </example>
protected virtual string CommentPrefix { get { return "//"; } }

// Lazy init compiler when it's actually needed
void InitCompiler() {
Expand Down Expand Up @@ -182,9 +179,7 @@ public abstract class ICodeDomCompiler : ICompiler
CompilerParameters args = new CompilerParameters();
args.GenerateExecutable = false;
args.IncludeDebugInformation = true;

if (dstPath != null) args.OutputAssembly = dstPath;
if (dstPath == null) args.GenerateInMemory = true;
args.OutputAssembly = dstPath;

for (int i = 0; i < srcPaths.Length; i++)
{
Expand Down
1 change: 0 additions & 1 deletion MCGalaxy/Modules/Compiling/CompilerOperations.cs
Expand Up @@ -79,7 +79,6 @@ public static class CompilerOperations
/// <param name="srcs"> Path of the source code files </param>
/// <param name="dst"> Path to the destination .dll </param>
/// <returns> The compiler results, or null if compilation failed </returns>
/// <remarks> If dstPath is null, compiles to an in-memory .dll instead. </remarks>
public static CompilerResults Compile(Player p, ICompiler compiler, string type, string[] srcs, string dst) {
foreach (string path in srcs)
{
Expand Down

0 comments on commit 5d8289d

Please sign in to comment.