From a6a04ec92d7044eec3713370ab75480ae7b57d0c Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 26 Mar 2021 22:39:47 +1100 Subject: [PATCH] Add Visual Basic plugin compiling and creating support --- CLI/MCGalaxyCLI.csproj | 3 - GUI/Popups/CustomCommands.cs | 9 ++- MCGalaxy/Commands/Scripting/CmdCmdCreate.cs | 16 ++-- MCGalaxy/Commands/Scripting/CmdCompile.cs | 15 ++-- MCGalaxy/Commands/Scripting/CmdPlugin.cs | 76 ++++++------------ MCGalaxy/Scripting/Backends.cs | 89 +++++++++++++++++++++ MCGalaxy/Scripting/Scripting.cs | 38 ++++++--- 7 files changed, 157 insertions(+), 89 deletions(-) diff --git a/CLI/MCGalaxyCLI.csproj b/CLI/MCGalaxyCLI.csproj index b69ef217f..73f4874da 100644 --- a/CLI/MCGalaxyCLI.csproj +++ b/CLI/MCGalaxyCLI.csproj @@ -64,8 +64,5 @@ MCGalaxy_ - - - \ No newline at end of file diff --git a/GUI/Popups/CustomCommands.cs b/GUI/Popups/CustomCommands.cs index 1c8fb9ca0..fc94fc808 100644 --- a/GUI/Popups/CustomCommands.cs +++ b/GUI/Popups/CustomCommands.cs @@ -39,13 +39,14 @@ public partial class CustomCommands : Form { } ICompiler engine = radVB.Checked ? ICompiler.VB : ICompiler.CS; - string path = engine.SourcePath(cmdName); + string path = engine.CommandPath(cmdName); if (File.Exists(path)) { Popup.Warning("Command already exists"); return; } try { - engine.CreateNew(path, cmdName); + string source = engine.GenExampleCommand(cmdName); + File.WriteAllText(path, source); } catch (Exception ex) { Logger.LogError(ex); Popup.Error("Failed to generate command. Check error logs for more details."); @@ -99,8 +100,8 @@ public partial class CustomCommands : Form { void lstCommands_SelectedIndexChanged(object sender, EventArgs e) { btnUnload.Enabled = lstCommands.SelectedIndex != -1; } - - + + void LoadCommands(Assembly assembly) { List commands = IScripting.LoadTypes(assembly); if (commands == null) { diff --git a/MCGalaxy/Commands/Scripting/CmdCmdCreate.cs b/MCGalaxy/Commands/Scripting/CmdCmdCreate.cs index 80e65c821..61fc5d926 100644 --- a/MCGalaxy/Commands/Scripting/CmdCmdCreate.cs +++ b/MCGalaxy/Commands/Scripting/CmdCmdCreate.cs @@ -30,22 +30,18 @@ public sealed class CmdCmdCreate : Command2 { if (message.Length == 0) { Help(p); return; } string[] args = message.SplitSpaces(); - ICompiler engine = null; - if (args.Length == 1) { - engine = ICompiler.CS; - } else if (args[1].CaselessEq("vb")) { - engine = ICompiler.VB; - } else { - Help(p); return; - } + string language = args.Length > 1 ? args[1] : ""; + ICompiler engine = ICompiler.Lookup(language, p); + if (engine == null) return; - string path = engine.SourcePath(args[0]); + string path = engine.CommandPath(args[0]); if (File.Exists(path)) { p.Message("File {0} already exists. Choose another name.", path); return; } try { - engine.CreateNew(path, args[0]); + string source = engine.GenExampleCommand(args[0]); + File.WriteAllText(path, source); } catch (Exception ex) { Logger.LogError("Error saving new command to " + path, ex); p.Message("An error occurred creating the command."); diff --git a/MCGalaxy/Commands/Scripting/CmdCompile.cs b/MCGalaxy/Commands/Scripting/CmdCompile.cs index 1f4c00b04..73f56b375 100644 --- a/MCGalaxy/Commands/Scripting/CmdCompile.cs +++ b/MCGalaxy/Commands/Scripting/CmdCompile.cs @@ -30,17 +30,12 @@ public sealed class CmdCompile : Command2 { public override void Use(Player p, string message, CommandData data) { if (message.Length == 0) { Help(p); return; } string[] args = message.SplitSpaces(); - - ICompiler engine = null; - if (args.Length == 1) { - engine = ICompiler.CS; - } else if (args[1].CaselessEq("vb")) { - engine = ICompiler.VB; - } else { - Help(p); return; - } - string srcPath = engine.SourcePath(args[0]); + string language = args.Length > 1 ? args[1] : ""; + ICompiler engine = ICompiler.Lookup(language, p); + if (engine == null) return; + + string srcPath = engine.CommandPath(args[0]); string dstPath = IScripting.CommandPath(args[0]); if (!File.Exists(srcPath)) { p.Message("File &9{0} &Snot found.", srcPath); return; diff --git a/MCGalaxy/Commands/Scripting/CmdPlugin.cs b/MCGalaxy/Commands/Scripting/CmdPlugin.cs index b748b5eec..58124b1b5 100644 --- a/MCGalaxy/Commands/Scripting/CmdPlugin.cs +++ b/MCGalaxy/Commands/Scripting/CmdPlugin.cs @@ -38,25 +38,29 @@ public sealed class CmdPlugin : Command2 { return; } - string[] parts = message.SplitSpaces(2); - if (parts.Length == 1) { Help(p); return; } - if (!Formatter.ValidName(p, parts[1], "plugin")) return; + string[] args = message.SplitSpaces(3); + if (args.Length == 1) { Help(p); return; } - if (parts[0].CaselessEq("load")) { - LoadPlugin(p, parts[1]); - } else if (parts[0].CaselessEq("unload")) { - UnloadPlugin(p, parts[1]); - } else if (parts[0].CaselessEq("create")) { - CreatePlugin(p, parts[1]); - } else if (parts[0].CaselessEq("compile")) { - CompilePlugin(p, parts[1]); + string cmd = args[0], name = args[1]; + if (!Formatter.ValidName(p, name, "plugin")) return; + string language = args.Length > 2 ? args[2] : ""; + + if (cmd.CaselessEq("load")) { + LoadPlugin(p, name); + } else if (cmd.CaselessEq("unload")) { + UnloadPlugin(p, name); + } else if (cmd.CaselessEq("create")) { + CreatePlugin(p, name, language); + } else if (cmd.CaselessEq("compile")) { + CompilePlugin(p, name, language); } else { Help(p); } } - static void CompilePlugin(Player p, string name) { - ICompiler engine = ICompiler.CS; + static void CompilePlugin(Player p, string name, string language) { + ICompiler engine = ICompiler.Lookup(language, p); + if (engine == null) return; string srcPath = "plugins/" + name + engine.Ext; string dstPath = IScripting.PluginPath(name); @@ -108,46 +112,18 @@ public sealed class CmdPlugin : Command2 { } } - static void CreatePlugin(Player p, string name) { + static void CreatePlugin(Player p, string name, string language) { + ICompiler engine = ICompiler.Lookup(language, p); + if (engine == null) return; + + string path = engine.PluginPath(name); p.Message("Creating a plugin example source"); - string creator = p.IsSuper ? Server.Config.Name : p.name; - string syntax = pluginSrc.Replace(@"\t", "\t"); - syntax = string.Format(syntax, name, creator, Server.Version); - File.WriteAllText("plugins/" + name + ".cs", syntax); + + string creator = p.IsSuper ? Server.Config.Name : p.truename; + string source = engine.GenExamplePlugin(name, creator); + File.WriteAllText(path, source); } - const string pluginSrc = - @"//This is an example plugin source! -using System; -namespace MCGalaxy -{{ -\tpublic class {0} : Plugin -\t{{ -\t\tpublic override string name {{ get {{ return ""{0}""; }} }} -\t\tpublic override string website {{ get {{ return ""www.example.com""; }} }} -\t\tpublic override string MCGalaxy_Version {{ get {{ return ""{2}""; }} }} -\t\tpublic override int build {{ get {{ return 100; }} }} -\t\tpublic override string welcome {{ get {{ return ""Loaded Message!""; }} }} -\t\tpublic override string creator {{ get {{ return ""{1}""; }} }} -\t\tpublic override bool LoadAtStartup {{ get {{ return true; }} }} - -\t\tpublic override void Load(bool startup) -\t\t{{ -\t\t\t//LOAD YOUR PLUGIN WITH EVENTS OR OTHER THINGS! -\t\t}} - -\t\tpublic override void Unload(bool shutdown) -\t\t{{ -\t\t\t//UNLOAD YOUR PLUGIN BY SAVING FILES OR DISPOSING OBJECTS! -\t\t}} - -\t\tpublic override void Help(Player p) -\t\t{{ -\t\t\t//HELP INFO! -\t\t}} -\t}} -}}"; - public override void Help(Player p) { p.Message("&T/Plugin create [name]"); p.Message("&HCreate a example .cs plugin file"); diff --git a/MCGalaxy/Scripting/Backends.cs b/MCGalaxy/Scripting/Backends.cs index 065835b9f..b84f97c8a 100644 --- a/MCGalaxy/Scripting/Backends.cs +++ b/MCGalaxy/Scripting/Backends.cs @@ -77,6 +77,40 @@ namespace MCGalaxy \t\t\tp.Message(""/{0} - Does stuff. Example command.""); \t\t}} \t}} +}}"; + } + } + + public override string PluginSkeleton { + get { + return @"//This is an example plugin source! +using System; +namespace MCGalaxy +{{ +\tpublic class {0} : Plugin +\t{{ +\t\tpublic override string name {{ get {{ return ""{0}""; }} }} +\t\tpublic override string MCGalaxy_Version {{ get {{ return ""{2}""; }} }} +\t\tpublic override int build {{ get {{ return 100; }} }} +\t\tpublic override string welcome {{ get {{ return ""Loaded Message!""; }} }} +\t\tpublic override string creator {{ get {{ return ""{1}""; }} }} +\t\tpublic override bool LoadAtStartup {{ get {{ return true; }} }} + +\t\tpublic override void Load(bool startup) +\t\t{{ +\t\t\t//LOAD YOUR PLUGIN WITH EVENTS OR OTHER THINGS! +\t\t}} + +\t\tpublic override void Unload(bool shutdown) +\t\t{{ +\t\t\t//UNLOAD YOUR PLUGIN BY SAVING FILES OR DISPOSING OBJECTS! +\t\t}} + +\t\tpublic override void Help(Player p) +\t\t{{ +\t\t\t//HELP INFO! +\t\t}} +\t}} }}"; } } @@ -154,6 +188,61 @@ Namespace MCGalaxy \t\t\tp.Message(""/{0} - Does stuff. Example command."") \t\tEnd Sub \tEnd Class +End Namespace"; + } + } + + public override string PluginSkeleton { + get { + return @"' This is an example plugin source! +Imports System + +Namespace MCGalaxy +\tPublic Class {0} +\t\tInherits Plugin +\t\tPublic Overrides ReadOnly Property name() As String +\t\t\tGet +\t\t\t\tReturn ""{0}"" +\t\t\tEnd Get +\t\t End Property +\t\tPublic Overrides ReadOnly Property MCGalaxy_Version() As String +\t\t\tGet +\t\t\t\tReturn ""{2}"" +\t\t\tEnd Get +\t\t End Property +\t\tPublic Overrides ReadOnly Property build() As Integer +\t\t\tGet +\t\t\t\tReturn 100 +\t\t\tEnd Get +\t\t End Property +\t\tPublic Overrides ReadOnly Property welcome() As String +\t\t\tGet +\t\t\t\tReturn ""Loaded Message!"" +\t\t\tEnd Get +\t\t End Property +\t\tPublic Overrides ReadOnly Property creator() As String +\t\t\tGet +\t\t\t\tReturn ""{1}"" +\t\t\tEnd Get +\t\t End Property +\t\tPublic Overrides ReadOnly Property LoadAtStartup() As Boolean +\t\t\tGet +\t\t\t\tReturn true +\t\t\tEnd Get +\t\t End Property + +\t\tPublic Overrides Sub Load(startup As Boolean) +\t\t\t' LOAD YOUR PLUGIN WITH EVENTS OR OTHER THINGS! +\t\tEnd Sub + +\t\tPublic Overrides Sub Unload(shutdown As Boolean) +\t\t\t' UNLOAD YOUR PLUGIN BY SAVING FILES OR DISPOSING OBJECTS! +\t\tEnd Sub + +\t\tPublic Overrides Sub Help(p As Player) +\t\t\t' HELP INFO! +\t\tEnd Sub +\tEnd Class End Namespace"; } } diff --git a/MCGalaxy/Scripting/Scripting.cs b/MCGalaxy/Scripting/Scripting.cs index 21da59742..fbcc6901c 100644 --- a/MCGalaxy/Scripting/Scripting.cs +++ b/MCGalaxy/Scripting/Scripting.cs @@ -145,27 +145,41 @@ public abstract class ICompiler { public const string ErrorPath = "logs/errors/compiler.log"; public abstract string Ext { get; } public abstract string CommandSkeleton { get; } + public abstract string PluginSkeleton { get; } - public string SourcePath(string cmdName) { return SourceDir + "Cmd" + cmdName + Ext; } + public string CommandPath(string name) { return SourceDir + "Cmd" + name + Ext; } + public string PluginPath(string name) { return "plugins/" + name + Ext; } /// C# compiler instance. public static ICompiler CS = new CSCompiler(); /// Visual Basic compiler instance. public static ICompiler VB = new VBCompiler(); - public void CreateNew(string path, string cmdName) { - cmdName = cmdName.ToLower(); + public static ICompiler Lookup(string name, Player p) { + if (name.Length == 0) return CS; + if (name.CaselessEq("CS")) return CS; + if (name.CaselessEq("VB")) return VB; - string syntax = CommandSkeleton; + p.Message("&WUnknown language \"{0}\"", name); + return null; + } + + + static string FormatSource(string source, params string[] args) { // Make sure we use the OS's line endings - syntax = syntax.Replace(@"\t", "\t"); - syntax = syntax.Replace("\r\n", "\n"); - syntax = syntax.Replace("\n", Environment.NewLine); - syntax = string.Format(syntax, cmdName.Capitalize()); - - using (StreamWriter sw = new StreamWriter(path)) { - sw.WriteLine(syntax); - } + source = source.Replace(@"\t", "\t"); + source = source.Replace("\r\n", "\n"); + source = source.Replace("\n", Environment.NewLine); + return string.Format(source, args); + } + + public string GenExampleCommand(string cmdName) { + cmdName = cmdName.ToLower().Capitalize(); + return FormatSource(CommandSkeleton, cmdName); + } + + public string GenExamplePlugin(string plugin, string creator) { + return FormatSource(PluginSkeleton, plugin, creator, Server.Version); } const int maxLog = 2;