mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -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.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@ -47,6 +48,11 @@ namespace MCGalaxy {
|
||||
|
||||
public Scripting() {
|
||||
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) {
|
||||
@ -86,12 +92,12 @@ namespace MCGalaxy {
|
||||
if (!Directory.Exists(DllDir))
|
||||
Directory.CreateDirectory(DllDir);
|
||||
|
||||
CompilerParameters args = new CompilerParameters();
|
||||
args.GenerateExecutable = false;
|
||||
args.MainClass = cmdName;
|
||||
args.OutputAssembly = DllDir + "Cmd" + cmdName + ".dll";
|
||||
args.ReferencedAssemblies.Add("MCGalaxy_.dll");
|
||||
string code = File.ReadAllText(path);
|
||||
results = compiler.CompileAssemblyFromSource(args, code.Replace("MCLawl", "MCGalaxy"));
|
||||
string source = File.ReadAllText(path);
|
||||
results = CompileSource(source, args);
|
||||
|
||||
switch (results.Errors.Count) {
|
||||
case 0:
|
||||
@ -132,6 +138,15 @@ namespace MCGalaxy {
|
||||
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>
|
||||
public static void Autoload() {
|
||||
if (!File.Exists(AutoloadFile)) { File.Create(AutoloadFile); return; }
|
||||
@ -142,7 +157,6 @@ namespace MCGalaxy {
|
||||
string error = Scripting.Load("Cmd" + cmd.ToLower());
|
||||
if (error != null) { Server.s.Log(error); continue; }
|
||||
Server.s.Log("AUTOLOAD: Loaded " + cmd.ToLower() + ".dll");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,20 +167,13 @@ namespace MCGalaxy {
|
||||
if (command.Length < 3 || command.Substring(0, 3).ToLower() != "cmd")
|
||||
return "Invalid command name specified.";
|
||||
try {
|
||||
//Allows unloading and deleting dlls without server restart
|
||||
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 (t.BaseType != typeof(Command)) continue;
|
||||
object instance = Activator.CreateInstance(t);
|
||||
|
||||
if (instance == null) {
|
||||
Server.s.Log("The command " + command + " couldn't be loaded!");
|
||||
throw new BadImageFormatException();
|
||||
}
|
||||
Command.all.Add((Command)instance);
|
||||
}
|
||||
if (commands.Count == 0) return null;
|
||||
foreach (Command cmd in commands)
|
||||
Command.all.Add(cmd);
|
||||
} catch (FileNotFoundException e) {
|
||||
Server.ErrorLog(e);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
@ -22,84 +22,38 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MCGalaxy.Util {
|
||||
|
||||
public sealed class MCGalaxyScripter {
|
||||
|
||||
private static readonly CompilerParameters _settings = new CompilerParameters(new [] {"mscorlib.dll", "MCGalaxy_.dll", "MCGalaxy.exe"}) {
|
||||
GenerateInMemory = true
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Compiles the specified source code.
|
||||
/// </summary>
|
||||
/// <summary> Compiles the specified source code. </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <param name="language">The language.</param>
|
||||
/// <returns>A result from the compilation</returns>
|
||||
public static CompileResult Compile ( string text, ScriptLanguage language ) {
|
||||
CodeDomProvider provider = null;
|
||||
|
||||
switch ( language ) {
|
||||
case ScriptLanguage.CSharp:
|
||||
provider = CodeDomProvider.CreateProvider( "CSharp" );
|
||||
break;
|
||||
case ScriptLanguage.VB:
|
||||
provider = CodeDomProvider.CreateProvider( "VisualBasic" );
|
||||
break;
|
||||
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 CompileResult Compile(string text, ScriptLanguage language) {
|
||||
Scripting scripting = language == ScriptLanguage.VB ? Scripting.VB : Scripting.CS;
|
||||
CompilerParameters args = new CompilerParameters();
|
||||
args.GenerateInMemory = true;
|
||||
|
||||
CompilerResults results = scripting.CompileSource(text, args);
|
||||
if (results.Errors.HasErrors)
|
||||
return new CompileResult(null, results.Errors);
|
||||
List<Command> list = Scripting.LoadFrom(results.CompiledAssembly);
|
||||
return new CompileResult(list.ToArray(), null);
|
||||
}
|
||||
|
||||
public static Command[] FromAssemblyFile ( string file ) {
|
||||
Assembly lib = Assembly.LoadFile ( file );
|
||||
var list = new List<Command>();
|
||||
|
||||
foreach ( var instance in lib.GetTypes().Where( t => t.BaseType == typeof( Command ) ).Select( Activator.CreateInstance ) ) {
|
||||
list.Add( (Command) instance );
|
||||
}
|
||||
|
||||
return list.ToArray ();
|
||||
public static Command[] FromAssemblyFile(string file) {
|
||||
Assembly lib = Assembly.LoadFile(file);
|
||||
return Scripting.LoadFrom(lib).ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public sealed class CompileResult {
|
||||
|
||||
/// <summary>
|
||||
/// Array of errors, if any.
|
||||
/// </summary>
|
||||
/// <summary> Array of errors, if any. </summary>
|
||||
public CompilerErrorCollection CompilerErrors { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the command object.
|
||||
/// </summary>
|
||||
/// <summary> Gets the command object. </summary>
|
||||
public Command[] Commands { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CompileResult"/> class.
|
||||
/// </summary>
|
||||
/// <summary> Initializes a new instance of the <see cref="CompileResult"/> class. </summary>
|
||||
/// <param name="commands">The command object.</param>
|
||||
/// <param name="errors">The errors.</param>
|
||||
public CompileResult ( Command[] commands, CompilerErrorCollection errors ) {
|
||||
@ -107,29 +61,16 @@ namespace MCGalaxy.Util {
|
||||
CompilerErrors = errors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CompileResult"/> class.
|
||||
/// </summary>
|
||||
/// <summary> Initializes a new instance of the <see cref="CompileResult"/> class. </summary>
|
||||
public CompileResult () { }
|
||||
}
|
||||
|
||||
public enum ScriptLanguage {
|
||||
|
||||
/// <summary>
|
||||
/// C#.net Scripting Interface Language
|
||||
/// </summary>
|
||||
/// <summary> C#.net Scripting Interface Language </summary>
|
||||
CSharp,
|
||||
|
||||
/// <summary>
|
||||
/// VB.net Scripting Interface Language
|
||||
/// </summary>
|
||||
/// <summary> VB.net Scripting Interface Language </summary>
|
||||
VB,
|
||||
|
||||
/// <summary>
|
||||
/// JavaScript Scripting Interface Language.
|
||||
/// NOTE: Not yet implemented
|
||||
/// </summary>
|
||||
/// <summary> JavaScript Scripting Interface Language. NOTE: Not yet implemented </summary>
|
||||
JavaScript
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user