Skip to content

Commit

Permalink
Add Visual Basic plugin compiling and creating support
Browse files Browse the repository at this point in the history
  • Loading branch information
UnknownShadow200 committed Mar 26, 2021
1 parent 5425c01 commit a6a04ec
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 89 deletions.
3 changes: 0 additions & 3 deletions CLI/MCGalaxyCLI.csproj
Expand Up @@ -64,8 +64,5 @@
<Name>MCGalaxy_</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
9 changes: 5 additions & 4 deletions GUI/Popups/CustomCommands.cs
Expand Up @@ -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.");
Expand Down Expand Up @@ -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<Command> commands = IScripting.LoadTypes<Command>(assembly);
if (commands == null) {
Expand Down
16 changes: 6 additions & 10 deletions MCGalaxy/Commands/Scripting/CmdCmdCreate.cs
Expand Up @@ -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.");
Expand Down
15 changes: 5 additions & 10 deletions MCGalaxy/Commands/Scripting/CmdCompile.cs
Expand Up @@ -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;
Expand Down
76 changes: 26 additions & 50 deletions MCGalaxy/Commands/Scripting/CmdPlugin.cs
Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand Down
89 changes: 89 additions & 0 deletions MCGalaxy/Scripting/Backends.cs
Expand Up @@ -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}}
}}";
}
}
Expand Down Expand Up @@ -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";
}
}
Expand Down
38 changes: 26 additions & 12 deletions MCGalaxy/Scripting/Scripting.cs
Expand Up @@ -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; }

/// <summary> C# compiler instance. </summary>
public static ICompiler CS = new CSCompiler();
/// <summary> Visual Basic compiler instance. </summary>
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;
Expand Down

0 comments on commit a6a04ec

Please sign in to comment.