mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
Reduce code duplication of Scripting.cs and MCForgeScripter.cs
This commit is contained in:
parent
5948804f11
commit
b551b63c65
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.CodeDom.Compiler;
|
using System.CodeDom.Compiler;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -47,6 +48,11 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
public Scripting() {
|
public Scripting() {
|
||||||
compiler = CodeDomProvider.CreateProvider(ProviderName);
|
compiler = CodeDomProvider.CreateProvider(ProviderName);
|
||||||
|
if (compiler == null) {
|
||||||
|
Server.s.Log("WARNING: Provider " + ProviderName +
|
||||||
|
" is missing, you will be unable to compile " + Ext + " commands.");
|
||||||
|
// TODO: Should we log "You must have .net developer tools. (You need a visual studio)" ?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateNew(string cmdName) {
|
public void CreateNew(string cmdName) {
|
||||||
@ -86,12 +92,12 @@ namespace MCGalaxy {
|
|||||||
if (!Directory.Exists(DllDir))
|
if (!Directory.Exists(DllDir))
|
||||||
Directory.CreateDirectory(DllDir);
|
Directory.CreateDirectory(DllDir);
|
||||||
|
|
||||||
|
CompilerParameters args = new CompilerParameters();
|
||||||
args.GenerateExecutable = false;
|
args.GenerateExecutable = false;
|
||||||
args.MainClass = cmdName;
|
args.MainClass = cmdName;
|
||||||
args.OutputAssembly = DllDir + "Cmd" + cmdName + ".dll";
|
args.OutputAssembly = DllDir + "Cmd" + cmdName + ".dll";
|
||||||
args.ReferencedAssemblies.Add("MCGalaxy_.dll");
|
string source = File.ReadAllText(path);
|
||||||
string code = File.ReadAllText(path);
|
results = CompileSource(source, args);
|
||||||
results = compiler.CompileAssemblyFromSource(args, code.Replace("MCLawl", "MCGalaxy"));
|
|
||||||
|
|
||||||
switch (results.Errors.Count) {
|
switch (results.Errors.Count) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -132,6 +138,15 @@ namespace MCGalaxy {
|
|||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CompilerResults CompileSource(string source, CompilerParameters args) {
|
||||||
|
args.ReferencedAssemblies.Add("MCGalaxy_.dll");
|
||||||
|
args.ReferencedAssemblies.Add("MCGalaxy.exe");
|
||||||
|
source = source.Replace("MCLawl", "MCGalaxy");
|
||||||
|
source = source.Replace("MCForge", "MCGalaxy");
|
||||||
|
return compiler.CompileAssemblyFromSource(args, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Automatically loads all .dll commands specified in the autoload file. </summary>
|
/// <summary> Automatically loads all .dll commands specified in the autoload file. </summary>
|
||||||
public static void Autoload() {
|
public static void Autoload() {
|
||||||
if (!File.Exists(AutoloadFile)) { File.Create(AutoloadFile); return; }
|
if (!File.Exists(AutoloadFile)) { File.Create(AutoloadFile); return; }
|
||||||
@ -142,7 +157,6 @@ namespace MCGalaxy {
|
|||||||
string error = Scripting.Load("Cmd" + cmd.ToLower());
|
string error = Scripting.Load("Cmd" + cmd.ToLower());
|
||||||
if (error != null) { Server.s.Log(error); continue; }
|
if (error != null) { Server.s.Log(error); continue; }
|
||||||
Server.s.Log("AUTOLOAD: Loaded " + cmd.ToLower() + ".dll");
|
Server.s.Log("AUTOLOAD: Loaded " + cmd.ToLower() + ".dll");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,20 +167,13 @@ namespace MCGalaxy {
|
|||||||
if (command.Length < 3 || command.Substring(0, 3).ToLower() != "cmd")
|
if (command.Length < 3 || command.Substring(0, 3).ToLower() != "cmd")
|
||||||
return "Invalid command name specified.";
|
return "Invalid command name specified.";
|
||||||
try {
|
try {
|
||||||
//Allows unloading and deleting dlls without server restart
|
|
||||||
byte[] data = File.ReadAllBytes(DllDir + command + ".dll");
|
byte[] data = File.ReadAllBytes(DllDir + command + ".dll");
|
||||||
Assembly lib = Assembly.Load(data);
|
Assembly lib = Assembly.Load(data); // TODO: Assembly.LoadFile instead?
|
||||||
|
List<Command> commands = LoadFrom(lib);
|
||||||
|
|
||||||
foreach (Type t in lib.GetTypes()) {
|
if (commands.Count == 0) return null;
|
||||||
if (t.BaseType != typeof(Command)) continue;
|
foreach (Command cmd in commands)
|
||||||
object instance = Activator.CreateInstance(t);
|
Command.all.Add(cmd);
|
||||||
|
|
||||||
if (instance == null) {
|
|
||||||
Server.s.Log("The command " + command + " couldn't be loaded!");
|
|
||||||
throw new BadImageFormatException();
|
|
||||||
}
|
|
||||||
Command.all.Add((Command)instance);
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Server.ErrorLog(e);
|
Server.ErrorLog(e);
|
||||||
return command + ".dll does not exist in the DLL folder, or is missing a dependency. Details in the error log.";
|
return command + ".dll does not exist in the DLL folder, or is missing a dependency. Details in the error log.";
|
||||||
@ -188,5 +195,22 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Command> LoadFrom(Assembly lib) {
|
||||||
|
//Allows unloading and deleting dlls without server restart
|
||||||
|
List<Command> commands = new List<Command>();
|
||||||
|
|
||||||
|
foreach (Type t in lib.GetTypes()) {
|
||||||
|
if (t.IsAbstract || !t.IsSubclassOf(typeof(Command)) )continue;
|
||||||
|
object instance = Activator.CreateInstance(t);
|
||||||
|
|
||||||
|
if (instance == null) {
|
||||||
|
Server.s.Log("Command \"" + t.Name + "\" could not be loaded.");
|
||||||
|
throw new BadImageFormatException();
|
||||||
|
}
|
||||||
|
commands.Add((Command)instance);
|
||||||
|
}
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2013 - Headdetect, And his almightyness
|
Copyright 2013 - Headdetect, And his almightyness
|
||||||
|
|
||||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||||
not use this file except in compliance with the Licenses. You may
|
not use this file except in compliance with the Licenses. You may
|
||||||
obtain a copy of the Licenses at
|
obtain a copy of the Licenses at
|
||||||
|
|
||||||
http://www.opensource.org/licenses/ecl2.php
|
http://www.opensource.org/licenses/ecl2.php
|
||||||
http://www.gnu.org/licenses/gpl-3.0.html
|
http://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing,
|
Unless required by applicable law or agreed to in writing,
|
||||||
software distributed under the Licenses are distributed on an "AS IS"
|
software distributed under the Licenses are distributed on an "AS IS"
|
||||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
or implied. See the Licenses for the specific language governing
|
or implied. See the Licenses for the specific language governing
|
||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.CodeDom.Compiler;
|
using System.CodeDom.Compiler;
|
||||||
@ -22,84 +22,38 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace MCGalaxy.Util {
|
namespace MCGalaxy.Util {
|
||||||
|
|
||||||
public sealed class MCGalaxyScripter {
|
public sealed class MCGalaxyScripter {
|
||||||
|
|
||||||
private static readonly CompilerParameters _settings = new CompilerParameters(new [] {"mscorlib.dll", "MCGalaxy_.dll", "MCGalaxy.exe"}) {
|
/// <summary> Compiles the specified source code. </summary>
|
||||||
GenerateInMemory = true
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compiles the specified source code.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text">The text.</param>
|
/// <param name="text">The text.</param>
|
||||||
/// <param name="language">The language.</param>
|
/// <param name="language">The language.</param>
|
||||||
/// <returns>A result from the compilation</returns>
|
/// <returns>A result from the compilation</returns>
|
||||||
public static CompileResult Compile ( string text, ScriptLanguage language ) {
|
public static CompileResult Compile(string text, ScriptLanguage language) {
|
||||||
CodeDomProvider provider = null;
|
Scripting scripting = language == ScriptLanguage.VB ? Scripting.VB : Scripting.CS;
|
||||||
|
CompilerParameters args = new CompilerParameters();
|
||||||
switch ( language ) {
|
args.GenerateInMemory = true;
|
||||||
case ScriptLanguage.CSharp:
|
|
||||||
provider = CodeDomProvider.CreateProvider( "CSharp" );
|
CompilerResults results = scripting.CompileSource(text, args);
|
||||||
break;
|
if (results.Errors.HasErrors)
|
||||||
case ScriptLanguage.VB:
|
return new CompileResult(null, results.Errors);
|
||||||
provider = CodeDomProvider.CreateProvider( "VisualBasic" );
|
List<Command> list = Scripting.LoadFrom(results.CompiledAssembly);
|
||||||
break;
|
return new CompileResult(list.ToArray(), null);
|
||||||
case ScriptLanguage.JavaScript:
|
|
||||||
throw new NotImplementedException( "This language interface has not been implemented yet." );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( provider == null ) {
|
|
||||||
throw new NotImplementedException( "You must have .net developer tools. (You need a visual studio)" );
|
|
||||||
}
|
|
||||||
|
|
||||||
var compile = provider.CompileAssemblyFromSource( _settings, text );
|
|
||||||
|
|
||||||
if ( compile.Errors.Count > 0 ) {
|
|
||||||
return new CompileResult( null, compile.Errors );
|
|
||||||
}
|
|
||||||
|
|
||||||
var assembly = compile.CompiledAssembly;
|
|
||||||
var list = new List<Command>();
|
|
||||||
|
|
||||||
foreach ( Command command in from type in assembly.GetTypes()
|
|
||||||
where type.BaseType == typeof( Command )
|
|
||||||
select Activator.CreateInstance( type ) as Command ) {
|
|
||||||
list.Add( command );
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CompileResult( list.ToArray(), null );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Command[] FromAssemblyFile ( string file ) {
|
public static Command[] FromAssemblyFile(string file) {
|
||||||
Assembly lib = Assembly.LoadFile ( file );
|
Assembly lib = Assembly.LoadFile(file);
|
||||||
var list = new List<Command>();
|
return Scripting.LoadFrom(lib).ToArray();
|
||||||
|
|
||||||
foreach ( var instance in lib.GetTypes().Where( t => t.BaseType == typeof( Command ) ).Select( Activator.CreateInstance ) ) {
|
|
||||||
list.Add( (Command) instance );
|
|
||||||
}
|
|
||||||
|
|
||||||
return list.ToArray ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class CompileResult {
|
public sealed class CompileResult {
|
||||||
|
/// <summary> Array of errors, if any. </summary>
|
||||||
/// <summary>
|
|
||||||
/// Array of errors, if any.
|
|
||||||
/// </summary>
|
|
||||||
public CompilerErrorCollection CompilerErrors { get; internal set; }
|
public CompilerErrorCollection CompilerErrors { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Gets the command object. </summary>
|
||||||
/// Gets the command object.
|
|
||||||
/// </summary>
|
|
||||||
public Command[] Commands { get; internal set; }
|
public Command[] Commands { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Initializes a new instance of the <see cref="CompileResult"/> class. </summary>
|
||||||
/// Initializes a new instance of the <see cref="CompileResult"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="commands">The command object.</param>
|
/// <param name="commands">The command object.</param>
|
||||||
/// <param name="errors">The errors.</param>
|
/// <param name="errors">The errors.</param>
|
||||||
public CompileResult ( Command[] commands, CompilerErrorCollection errors ) {
|
public CompileResult ( Command[] commands, CompilerErrorCollection errors ) {
|
||||||
@ -107,29 +61,16 @@ namespace MCGalaxy.Util {
|
|||||||
CompilerErrors = errors;
|
CompilerErrors = errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Initializes a new instance of the <see cref="CompileResult"/> class. </summary>
|
||||||
/// Initializes a new instance of the <see cref="CompileResult"/> class.
|
|
||||||
/// </summary>
|
|
||||||
public CompileResult () { }
|
public CompileResult () { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ScriptLanguage {
|
public enum ScriptLanguage {
|
||||||
|
/// <summary> C#.net Scripting Interface Language </summary>
|
||||||
/// <summary>
|
|
||||||
/// C#.net Scripting Interface Language
|
|
||||||
/// </summary>
|
|
||||||
CSharp,
|
CSharp,
|
||||||
|
/// <summary> VB.net Scripting Interface Language </summary>
|
||||||
/// <summary>
|
|
||||||
/// VB.net Scripting Interface Language
|
|
||||||
/// </summary>
|
|
||||||
VB,
|
VB,
|
||||||
|
/// <summary> JavaScript Scripting Interface Language. NOTE: Not yet implemented </summary>
|
||||||
/// <summary>
|
|
||||||
/// JavaScript Scripting Interface Language.
|
|
||||||
/// NOTE: Not yet implemented
|
|
||||||
/// </summary>
|
|
||||||
JavaScript
|
JavaScript
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user