Allow referencing external assemblies in .cs/.vb custom commands (thanks roon)

This commit is contained in:
UnknownShadow200 2017-01-25 18:54:40 +11:00
parent c15f7b1ce8
commit bfb25a9ee1
8 changed files with 52 additions and 58 deletions

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
using System.IO;
using MCGalaxy.Bots;
@ -78,13 +79,10 @@ namespace MCGalaxy.Commands
}
static void DeleteLast(Player p, string ai) {
string[] Lines = File.ReadAllLines("bots/" + ai);
string[] outLines = new string[Lines.Length - 1];
for (int i = 0; i < Lines.Length - 1; i++) {
outLines[i] = Lines[i];
}
List<string> lines = Utils.ReadAllLinesList("bots/" + ai);
if (lines.Count > 0) lines.RemoveAt(lines.Count - 1);
File.WriteAllLines("bots/" + ai, outLines);
File.WriteAllLines("bots/" + ai, lines.ToArray());
Player.Message(p, "Deleted the last instruction from " + ai);
}

View File

@ -51,8 +51,7 @@ namespace MCGalaxy.Commands {
if (File.Exists("extra/text/" + args[0] + ".txt")) {
string[] lines = File.ReadAllLines("extra/text/" + args[0] + ".txt");
for (int i = 0; i < lines.Length; i++)
Player.Message(who, lines[i]);
Player.MessageLines(who, lines);
} else {
Player.Message(p, "File specified doesn't exist");
}

View File

@ -228,9 +228,8 @@ namespace MCGalaxy.Games {
try {
if (!File.Exists("text/infectmessages.txt"))
File.WriteAllLines("text/infectmessages.txt", defMessages);
string[] lines = File.ReadAllLines("text/infectmessages.txt");
infectMessages = new List<string>(lines);
infectMessages = Utils.ReadAllLinesList("text/infectmessages.txt");
} catch (Exception ex) {
Server.ErrorLog(ex);
}

View File

@ -143,8 +143,9 @@ namespace MCGalaxy {
File.WriteAllLines("text/irccmdblacklist.txt", new string[] {
"#Here you can put commands that cannot be used from the IRC bot.",
"#Lines starting with \"#\" are ignored." });
foreach (string line in File.ReadAllLines("text/irccmdblacklist.txt"))
foreach (string line in File.ReadAllLines("text/irccmdblacklist.txt")) {
if (line[0] != '#') banCmd.Add(line);
}
}
}

View File

@ -27,15 +27,15 @@ namespace MCGalaxy {
public override string CommandSkeleton {
get {
return @"/*
\tAuto-generated command skeleton class.
return @"//\tAuto-generated command skeleton class.
//\tUse this as a basis for custom MCGalaxy commands.
//\tFile and class should be named a specific way. For example, /update is named 'CmdUpdate.cs' for the file, and 'CmdUpdate' for the class.
// As a note, MCGalaxy is designed for .NET 4.0
\tUse this as a basis for custom commands implemented via the MCGalaxy scripting framework.
\tFile and class should be named a specific way. For example, /update is named 'CmdUpdate.cs' for the file, and 'CmdUpdate' for the class.
*/
// To reference other assemblies, put a ""Reference [assembly filename]"" at the top of the file
// e.g. to reference the System.Data assembly, put ""Reference System.Data.dll""
// Add any other using statements you need up here, of course.
// As a note, MCGalaxy is designed for .NET 3.5.
// Add any other using statements you need after this
using System;
namespace MCGalaxy
@ -84,13 +84,16 @@ namespace MCGalaxy
public override string CommandSkeleton {
get {
return @"Imports MCGalaxy
'Auto-generated command skeleton class.
'Use this as a basis for custom commands implemented via the MCGalaxy scripting framework.
'File and class should be named a specific way. For example, /update is named 'CmdUpdate.vb' for the file, and 'CmdUpdate' for the class.
'
' Add any other using statements you need up here, of course.
' As a note, MCGalaxy is designed for .NET 3.5.
return @"'\tAuto-generated command skeleton class.
'\tUse this as a basis for custom MCGalaxy commands.
'\tFile and class should be named a specific way. For example, /update is named 'CmdUpdate.vb' for the file, and 'CmdUpdate' for the class.
' As a note, MCGalaxy is designed for .NET 4.0.
' To reference other assemblies, put a ""Reference [assembly filename]"" at the top of the file
' e.g. to reference the System.Data assembly, put ""Reference System.Data.dll""
' Add any other Imports statements you need after this
Imports System
Namespace MCGalaxy
\tPublic Class Cmd{0}

View File

@ -97,7 +97,7 @@ namespace MCGalaxy {
args.MainClass = cmdName;
args.OutputAssembly = DllDir + "Cmd" + cmdName + ".dll";
string source = File.ReadAllText(path);
string source = ReadSourceCode(path, args);
results = CompileSource(source, args);
if (!results.Errors.HasErrors) return true;
@ -116,6 +116,20 @@ namespace MCGalaxy {
return false;
}
string ReadSourceCode(string path, CompilerParameters args) {
List<string> lines = Utils.ReadAllLinesList(path);
// Allow referencing other assemblies using 'Reference [assembly name]' at top of the file
for (int i = 0; i < lines.Count; i++) {
if (!lines[i].CaselessStarts("reference ")) break;
int index = lines[i].IndexOf(' ') + 1;
string assem = lines[i].Substring(index);
args.ReferencedAssemblies.Add(assem);
lines.RemoveAt(i); i--;
}
return lines.Join(Environment.NewLine);
}
void AppendDivider(StringBuilder sb, bool exists) {
if (!exists) return;
sb.AppendLine();

View File

@ -117,8 +117,7 @@ namespace MCGalaxy.Tasks {
string propFile = LevelInfo.FindPropertiesFile(name);
List<string> lines = new List<string>();
if (propFile != null) {
string[] rawLines = File.ReadAllLines(propFile);
lines = new List<string>(rawLines);
lines = Utils.ReadAllLinesList(propFile);
}
using (StreamReader r = new StreamReader(envFile)) {

View File

@ -17,7 +17,9 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
namespace MCGalaxy {
@ -106,38 +108,17 @@ namespace MCGalaxy {
result = temp;
return true;
}
const StringComparison comp = StringComparison.OrdinalIgnoreCase;
public static T FindMatches<T>(Player pl, string name, out int matches, IEnumerable items,
Predicate<T> filter, Func<T, string> nameGetter, string type, int limit = 5) {
T match = default(T); matches = 0;
name = name.ToLower();
StringBuilder matchNames = new StringBuilder();
foreach (T item in items) {
if (!filter(item)) continue;
string itemName = nameGetter(item);
if (itemName.Equals(name, comp)) { matches = 1; return item; }
if (itemName.IndexOf(name, comp) < 0) continue;
match = item; matches++;
if (matches <= limit)
matchNames.Append(itemName).Append(", ");
else if (matches == limit + 1)
matchNames.Append("(and more)").Append(", ");
}
if (matches == 0) {
Player.Message(pl, "No " + type + " match \"" + name + "\"."); return default(T);
} else if (matches == 1) {
return match;
} else {
string count = matches > limit ? limit + "+ " : matches + " ";
string names = matchNames.ToString(0, matchNames.Length - 2);
Player.Message(pl, count + type + " match \"" + name + "\":");
Player.Message(pl, names); return default(T);
public static List<string> ReadAllLinesList(String path) {
List<string> lines = new List<string>();
using (StreamReader r = new StreamReader(path)) {
string item;
while ((item = r.ReadLine()) != null) {
lines.Add(item);
}
}
return lines;
}
}
}