diff --git a/MudEngine/WinPC_Engine/Core/Interfaces/ISavable.cs b/MudEngine/WinPC_Engine/Core/Interfaces/ISavable.cs
index fce1efd..d518d20 100644
--- a/MudEngine/WinPC_Engine/Core/Interfaces/ISavable.cs
+++ b/MudEngine/WinPC_Engine/Core/Interfaces/ISavable.cs
@@ -19,7 +19,9 @@ namespace MudEngine.Core.Interfaces
/// Save method for dumping the object to physical file.
///
///
- void Save(String path);
+ Boolean Save(String filename);
+
+ Boolean Save(String filename, Boolean ignoreignoreFileWrite);
///
/// Load method for retrieving saved data from file.
diff --git a/MudEngine/WinPC_Engine/Core/ObjectCollection.cs b/MudEngine/WinPC_Engine/Core/ObjectCollection.cs
new file mode 100644
index 0000000..51c0b36
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/ObjectCollection.cs
@@ -0,0 +1,139 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using MudEngine.Game;
+using MudEngine.GameScripts;
+using MudEngine.Scripting;
+
+namespace MudEngine.Core
+{
+ internal class ObjectCollection : ICollection
+ {
+ #region Public Properties
+ public Boolean IsReadOnly
+ {
+ get { return this.isReadOnly; }
+ }
+ #endregion
+
+ #region public Methods
+
+ #endregion
+
+ #region public Interface Methods
+ ///
+ /// Adds a new Scripted Object to the games Object Manager.
+ ///
+ ///
+ public void Add(BaseScript item)
+ {
+ //Checks if the Object Manager is currently in Read-Only mode.
+ if (this.isReadOnly)
+ {
+ Logger.WriteLine("Warning: Attempted to add a scripted object while the Object Manager is Read Only.");
+ return;
+ }
+
+ //TODO: Allow the same Scripts to be used provided different ID's are assigned.
+ if (!this.Contains(item))
+ this.scriptCollection.Add(item);
+ else
+ Logger.WriteLine("Warning: Scripted object (" + item.ID.ToString() + ")" + item.Name + " was not added to the Object Manager due to being a duplicate.");
+ }
+
+ ///
+ /// Clears the Object Manager of all Scripted Objects
+ ///
+ public void Clear()
+ {
+ this.scriptCollection.Clear();
+ }
+
+ ///
+ /// Checks if the Object Manager currently has a Scripted Object matching the supplied Object.
+ ///
+ ///
+ ///
+ public Boolean Contains(BaseScript item)
+ {
+ bool isFound = false;
+
+ foreach (BaseScript script in this.scriptCollection)
+ {
+ if (script.Equals(item))
+ {
+ isFound = true;
+ break;
+ }
+ }
+
+ return isFound;
+ }
+
+ public void CopyTo(BaseScript[] array, int arrayIndex)
+ {
+ this.scriptCollection.CopyTo(array, arrayIndex);
+ }
+
+ public Int32 Count
+ {
+ get { return this.scriptCollection.Count; }
+ }
+
+ public bool Remove(BaseScript item)
+ {
+ if (this.Contains(item))
+ {
+ this.scriptCollection.Remove(item);
+ return true;
+ }
+
+ return false;
+ }
+
+ public Int32 Length { get { return this.scriptCollection.Count; } }
+
+ public IEnumerator GetEnumerator()
+ {
+ return new ScriptEnumerator(this);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return new ScriptEnumerator(this);
+ }
+ #endregion
+
+ #region Constructors
+ public ObjectCollection(StandardGame game)
+ {
+ this.scriptCollection = new List();
+ this.isReadOnly = false;
+
+ this._Game = game;
+ }
+
+ ///
+ /// Get or Set a index value for this collection
+ ///
+ ///
+ ///
+ public BaseScript this[Int32 index]
+ {
+ //TODO: Perform some exception handling here.
+ //TODO: Don't allow setting if isReadOnly=true
+ get { return (BaseScript)this.scriptCollection[index]; }
+ set { this.scriptCollection[index] = value; }
+ }
+ #endregion
+
+ #region Private Fields
+ private List scriptCollection;
+ private Boolean isReadOnly;
+ private StandardGame _Game;
+ #endregion
+ }
+}
diff --git a/MudEngine/WinPC_Engine/DAL/XMLData.cs b/MudEngine/WinPC_Engine/DAL/XMLData.cs
new file mode 100644
index 0000000..b255c94
--- /dev/null
+++ b/MudEngine/WinPC_Engine/DAL/XMLData.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+using System.Reflection;
+
+using MudEngine.GameScripts;
+
+namespace MudEngine.DAL
+{
+ public class XMLData
+ {
+ public XElement SaveData { get; private set; }
+
+ ///
+ /// Instances the ObjectSaver and all of its Properties and Fields
+ ///
+ public XMLData(String objectType)
+ {
+ SaveData = new XElement(objectType);
+ }
+
+ public void AddSaveData(String property, String value)
+ {
+ this.SaveData.Add(new XElement(property, value));
+ }
+
+ public Boolean Save(String filename)
+ {
+ this.SaveData.Save(filename);
+ return true;
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/DAL/XmlParser.cs b/MudEngine/WinPC_Engine/DAL/XmlParser.cs
deleted file mode 100644
index 4e18fb0..0000000
--- a/MudEngine/WinPC_Engine/DAL/XmlParser.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MudEngine.DAL
-{
- public class XmlParser
- {
-
- }
-}
diff --git a/MudEngine/WinPC_Engine/Game/Characters/MyCharacter.cs b/MudEngine/WinPC_Engine/Game/Characters/MyCharacter.cs
new file mode 100644
index 0000000..695c3f9
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Game/Characters/MyCharacter.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using MudEngine.Game;
+
+namespace MudEngine.Game.Characters
+{
+ class MyCharacter : StandardCharacter
+ {
+ public int Age { get; set; }
+
+ public MyCharacter(StandardGame game, String name, String desc)
+ : base(game, name, desc)
+ {
+ }
+
+ public override bool Save(string filename)
+ {
+ base.Save(filename, true);
+
+ this.SaveData.AddSaveData("Age", Age.ToString());
+ return this.SaveData.Save(filename);
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Game/Characters/StandardCharacter.cs b/MudEngine/WinPC_Engine/Game/Characters/StandardCharacter.cs
index 1ddf003..b2dc6e3 100644
--- a/MudEngine/WinPC_Engine/Game/Characters/StandardCharacter.cs
+++ b/MudEngine/WinPC_Engine/Game/Characters/StandardCharacter.cs
@@ -6,6 +6,7 @@ using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
+using System.Xml.Linq;
using MudEngine.GameScripts;
using MudEngine.Core.Interfaces;
@@ -47,18 +48,18 @@ namespace MudEngine.Game.Characters
protected CommandSystem Commands { get; private set; }
- public StandardCharacter(String name, String description, StandardGame game) : base(name, description)
+ public StandardCharacter(StandardGame game, String name, String description) : base(game, name, description)
{
this.Game = game;
//Instance this Characters personal Command System with a copy of the command
//collection already loaded and prepared by the Active Game.
this.Commands = new CommandSystem(CommandSystem.Commands);
-
+
this.OnConnectEvent += new OnConnectHandler(OnConnect);
}
- public StandardCharacter(String name, String description, StandardGame game, Socket connection) : this(name, description, game)
+ public StandardCharacter(StandardGame game, String name, String description, Socket connection) : this(game, name, description)
{
this._Connection = connection;
@@ -69,6 +70,18 @@ namespace MudEngine.Game.Characters
this._InitialMessage = true; //Strips Telnet client garbage text from initial message sent from client.
}
+ public override bool Save(String filename)
+ {
+ base.Save(filename, true);
+
+ SaveData.AddSaveData("Immovable", Immovable.ToString());
+ SaveData.AddSaveData("Password", Password);
+
+ this.SaveData.Save(filename);
+
+ return true;
+ }
+
internal void ExecuteCommand(string command)
{
//Process commands here.
@@ -176,11 +189,6 @@ namespace MudEngine.Game.Characters
}
}
- public void Save(string path)
- {
- throw new NotImplementedException();
- }
-
public void Load(string filename)
{
throw new NotImplementedException();
diff --git a/MudEngine/WinPC_Engine/GameScripts/BaseScript.cs b/MudEngine/WinPC_Engine/GameScripts/BaseScript.cs
index 3f59904..90cb0e1 100644
--- a/MudEngine/WinPC_Engine/GameScripts/BaseScript.cs
+++ b/MudEngine/WinPC_Engine/GameScripts/BaseScript.cs
@@ -3,20 +3,76 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
+using System.Xml.Linq;
+using System.IO;
+
+using MudEngine.Game;
+using MudEngine.DAL;
namespace MudEngine.GameScripts
{
public class BaseScript
{
+ [DefaultValue("Scripted Object")]
public String Name { get; set; }
public String ID { get; set; }
public String Description { get; set; }
- public BaseScript(String name, String description)
+ public XMLData SaveData { get; protected set; }
+
+ public BaseScript(StandardGame game, String name, String description)
{
+ this.Name = name;
+ this.Description = description;
+
this.ID = Guid.NewGuid().ToString();
+
+ this.SaveData = new XMLData(this.GetType().Name);
+ }
+
+ public virtual Boolean Save(String filename)
+ {
+ return this.Save(filename, false);
+ }
+
+ public virtual Boolean Save(String filename, Boolean ignoreFileWrite)
+ {
+ if (File.Exists(filename))
+ File.Delete(filename);
+
+ try
+ {
+ this.SaveData.AddSaveData("Name", Name);
+ this.SaveData.AddSaveData("ID", ID);
+ this.SaveData.AddSaveData("Description", Description);
+
+ if (!ignoreFileWrite)
+ this.SaveData.Save(filename);
+ }
+ catch
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public virtual Boolean Load(String filename)
+ {
+ try
+ {
+ if (!File.Exists(filename))
+ return false;
+
+ XElement data = XElement.Load(filename);
+ }
+ catch
+ {
+ return false;
+ }
+ return true;
}
public override string ToString()
diff --git a/MudEngine/WinPC_Engine/Networking/ConnectionManager.cs b/MudEngine/WinPC_Engine/Networking/ConnectionManager.cs
index a923c23..71f76ae 100644
--- a/MudEngine/WinPC_Engine/Networking/ConnectionManager.cs
+++ b/MudEngine/WinPC_Engine/Networking/ConnectionManager.cs
@@ -29,7 +29,7 @@ namespace MudEngine.Networking
Connections = new List();
//Instance a new character and provide it with the Socket.
- StandardCharacter character = new StandardCharacter("New Player", "New networked client.", game, connection);
+ StandardCharacter character = new StandardCharacter(game, "New Player", "New networked client.", connection);
//Add it to the Connections collection
Connections.Add(character);
diff --git a/MudEngine/WinPC_Engine/Scripting/CSharp.cs b/MudEngine/WinPC_Engine/Scripting/CSharp.cs
new file mode 100644
index 0000000..9cf0f00
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Scripting/CSharp.cs
@@ -0,0 +1,126 @@
+using System;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.IO;
+#if WINDOWS_PC
+using Microsoft.CSharp;
+#endif
+
+namespace MudEngine.Scripting
+{
+ ///
+ /// Standard C# source code compiler.
+ ///
+ internal class CSharp : ICompiler
+ {
+#if WINDOWS_PC
+ ///
+ /// The file extension used for the script files.
+ ///
+ public String ScriptExtension { get; set; }
+
+ ///
+ /// Provides a collection of Assemblies that the compiler will add to its reference list.
+ ///
+ public List AssemblyReferences { get; set; }
+
+ ///
+ /// The results of the compilation
+ ///
+ public CompilerResults Results { get; set; }
+
+ ///
+ /// Provides compiling options to various compilers, if they support this feature.
+ ///
+ public Dictionary CompilerOptions { get; set; }
+
+ ///
+ /// Compiles the source files found within the scriptRepository directory matching the ICompiler.ScriptExtension
+ /// The Compiler defaults to the C# 4.0 compiler if none other is supplied via the ICompiler.CompilerOptions argument.
+ ///
+ /// Compiler Parameters that can be supplied to customize the compilation of the source.
+ /// Returns true if the compilation was completed without error.
+ public Boolean Compile(CompilerParameters param, String scriptRepository)
+ {
+ //Make sure we have a compiler version supplied.
+ if (!CompilerOptions.ContainsKey("CompilerVersion"))
+ CompilerOptions.Add("CompilerVersion", "v4.0");
+
+ //Instance a reference to the C# code provider, this is what will perform the compiling.
+ CSharpCodeProvider provider = new CSharpCodeProvider(CompilerOptions);
+ //Create an array of script files found within the ScriptRepository matching the ScriptExtension properties.
+ String[] scripts = Directory.GetFiles(scriptRepository, "*" + this.ScriptExtension, SearchOption.AllDirectories);
+
+ //Compile the scripts and provide the Results property with a reference to the compilation results.
+ Results = provider.CompileAssemblyFromFile(param, scripts);
+
+ //if the compiler has errors, return false.
+ if (Results.Errors.HasErrors)
+ return false;
+ else
+ return true;
+ }
+
+ ///
+ /// Compiles the source files found within the scriptFile argument.
+ /// The Compiler defaults to the C# 4.0 compiler if none other is supplied via the ICompiler.CompilerOptions argument.
+ ///
+ ///
+ ///
+ public Boolean Compile(CompilerParameters param, FileInfo scriptFile)
+ {
+ //Make sure we have a compiler version supplied.
+ if (!CompilerOptions.ContainsKey("CompilerVersion"))
+ CompilerOptions.Add("CompilerVersion", "v4.0");
+
+ CSharpCodeProvider provider = new CSharpCodeProvider(CompilerOptions);
+
+ //Make sure the file exists prior to attempting to compile it.
+ if (scriptFile.Exists)
+ {
+ //Compile the script and provide the Results property with a referece to the compilation results.
+ Results = provider.CompileAssemblyFromFile(param, scriptFile.FullName);
+ }
+ else
+ {
+ Results.Errors.Add(new CompilerError(scriptFile.FullName, 0, 0, "rS01", "The supplied filename does not exist."));
+ return false;
+ }
+
+ if (Results.Errors.HasErrors)
+ return false;
+ else
+ return true;
+ }
+
+ ///
+ /// Compiles the source code found within the scriptSourceCode argument
+ /// The Compiler defaults to the C# 4.0 compiler if none other is supplied via the ICompiler.CompilerOptions argument.
+ ///
+ ///
+ ///
+ public Boolean Compile(CompilerParameters param, String[] scriptSourceCode)
+ {
+ if (!CompilerOptions.ContainsKey("CompilerVersion"))
+ CompilerOptions.Add("CompilerVersion", "v4.0");
+
+ CSharpCodeProvider provider = new CSharpCodeProvider(CompilerOptions);
+
+ if (scriptSourceCode.Length == 0)
+ {
+ Results.Errors.Add(new CompilerError("None", 0, 0, "rS02", "No Source provided."));
+ return false;
+ }
+ else
+ {
+ Results = provider.CompileAssemblyFromSource(param, scriptSourceCode);
+ }
+
+ if (Results.Errors.HasErrors)
+ return false;
+ else
+ return true;
+ }
+#endif
+ }
+}
\ No newline at end of file
diff --git a/MudEngine/WinPC_Engine/Scripting/CompileEngine.cs b/MudEngine/WinPC_Engine/Scripting/CompileEngine.cs
new file mode 100644
index 0000000..4169357
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Scripting/CompileEngine.cs
@@ -0,0 +1,415 @@
+using System;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+#if WINDOWS_PC
+using Microsoft.CSharp;
+#endif
+namespace MudEngine.Scripting
+{
+ ///
+ /// Provides Properties & Methods needed to compile script source code into .NET assemblies.
+ ///
+ public class CompileEngine
+ {
+ ///
+ /// The file extension used for the script files.
+ ///
+ public String ScriptExtension
+ {
+ get
+ {
+ return _ScriptExtension;
+ }
+ set
+ {
+ if (value.StartsWith("."))
+ _ScriptExtension = value;
+ else
+ _ScriptExtension = "." + value;
+ }
+ }
+ private String _ScriptExtension;
+
+ ///
+ /// Provides a collection of Assemblies that the compiler will add to its reference list.
+ ///
+ public List AssemblyReferences { get; private set; }
+
+ ///
+ /// Provides a reference to the assembly generated during script compilation.
+ ///
+ public Assembly CompiledAssembly { get; set; }
+
+ ///
+ /// The compiler that will be used when the contents of ScriptRepository are compiled.
+ ///
+ public String Compiler { get; set; }
+
+ ///
+ /// Used to supply compiling options to various compilers if they support this feature.
+ ///
+ public Dictionary CompilerOptions { get; set; }
+
+ ///
+ /// Used to check if the compilation contained any errors.
+ ///
+ public Boolean HasErrors { get; internal set; }
+
+ ///
+ /// String of errors that occurred during compilation, if any.
+ ///
+ public String Errors
+ {
+ get
+ {
+ if (_CompileMessages.Length == 0)
+ return "No Errors.";
+ else
+ {
+ StringBuilder builder = new StringBuilder();
+ foreach (String error in _CompileMessages)
+ {
+ builder.AppendLine(error);
+ }
+
+ return builder.ToString();
+ }
+ }
+ }
+
+ //Messages stored from the compilers CompilerResults property.
+ private String[] _CompileMessages;
+
+ //Returns all of the assemblies currently loaded in the current domain.
+ private Assembly[] _Assemblies
+ {
+ get
+ {
+ return AppDomain.CurrentDomain.GetAssemblies();
+ }
+ }
+
+ public CompileEngine() : this(".cs")
+ {
+ //Passes defaults off to the parameterized constructor.
+ }
+
+ public CompileEngine(String scriptExtensions)
+ {
+ _CompileMessages = new String[] { "No compiler messages available." };
+
+ CompilerOptions = new Dictionary();
+ Compiler = "C#";
+
+ AssemblyReferences = new List();
+ AssemblyReferences.Add("mscorlib.dll");
+ AssemblyReferences.Add("System.dll");
+ AssemblyReferences.Add("System.Core.dll");
+
+ ScriptExtension = scriptExtensions;
+ }
+
+ ///
+ /// Adds a reference to the supplied Assembly name to the compilers reference collection.
+ ///
+ ///
+ public void AddAssemblyReference(String assembly)
+ {
+ if (!AssemblyReferences.Contains(assembly))
+ AssemblyReferences.Add(assembly);
+ }
+
+ ///
+ /// Adds a reference to the supplied Assembly to the compilers reference collection.
+ ///
+ ///
+ public void AddAssemblyReference(Assembly assembly)
+ {
+ if (!AssemblyReferences.Contains(assembly.GetName().Name))
+ AssemblyReferences.Add(assembly.GetName().Name);
+ }
+
+ ///
+ /// Removes the supplied assembly from the compilers reference collection.
+ ///
+ ///
+ public void RemoveAssemblyReference(String assembly)
+ {
+ if (AssemblyReferences.Contains(assembly))
+ AssemblyReferences.Remove(assembly);
+ }
+
+ ///
+ /// Clears the compilers reference collection, leaving it empty.
+ ///
+ public void ClearAssemblyReference()
+ {
+ AssemblyReferences.Clear();
+ }
+
+ ///
+ /// Compiles the scripts found within the CompileEngine.ScriptRepository directory that match the CompileEngine.ScriptExtension file extension.
+ /// The compiler will compile the scripts using the compiler specified with the CompileEngine.Compiler Property.
+ ///
+ /// Returns true if compilation was completed without any errors.
+ public Boolean Compile(String scriptRepository)
+ {
+#if WINDOWS_PC
+ //Get the compiler that the developer has selected.
+ //If the developer chooses a compiler that is not part of the engine, the GetCompiler() method
+ //will check all the currently loaded assemblies in memory for a custom compiler implementing
+ //the ICompiler interface.
+ Type compiler = GetCompiler();
+
+ //Incase a non-default compiler was specified and we could not find it in memory, fail.
+ if (compiler.Name == "ICompiler")
+ {
+ this._CompileMessages = new string[] { "Compilation Failed.", "Unable to locate the specified compiler of Type '" + Compiler + "'." };
+ return false;
+ }
+
+ //Get the compiler parameters.
+ CompilerParameters param = GetParameters();
+
+ //Create a Instance of the compiler, either custom or internal.
+ ICompiler com = (ICompiler)Activator.CreateInstance(compiler);
+
+ //Setup it's properties to match that of our CompileEngine.
+ com.AssemblyReferences = AssemblyReferences;
+ com.ScriptExtension = ScriptExtension;
+ com.CompilerOptions = this.CompilerOptions;
+
+ //Compile the scripts.
+ Boolean isSuccess = com.Compile(param, scriptRepository);
+ HasErrors = !isSuccess;
+
+ //If the compilation failed, store all of the compiler errors
+ //into our _CompileMessages string.
+ if (!isSuccess)
+ {
+ List compilerMessages = new List();
+ foreach (String message in com.Results.Output)
+ {
+ compilerMessages.Add(message);
+ }
+
+ _CompileMessages = compilerMessages.ToArray();
+ return false;
+ }
+ else
+ {
+ //Compiling completed without error, so we need to save
+ //a reference to the compiled assembly.
+ CompiledAssembly = com.Results.CompiledAssembly;
+ return true;
+ }
+#else
+ return false;
+#endif
+ }
+
+ ///
+ /// Compiles the script supplied.
+ /// The compiler will compile the script using the compiler specified with the CompileEngine.Compiler Property.
+ ///
+ /// Returns true if compilation was completed without any errors.
+ public Boolean Compile(FileInfo sourceFile)
+ {
+#if WINDOWS_PC
+ if (!sourceFile.Exists)
+ {
+ this._CompileMessages = new String[] { "Error: File " + sourceFile.FullName + " does not exists." };
+ return false;
+ }
+
+ //Get the compiler that the developer has selected.
+ //If the developer chooses a compiler that is not part of the engine, the GetCompiler() method
+ //will check all the currently loaded assemblies in memory for a custom compiler implementing
+ //the ICompiler interface.
+ Type compiler = GetCompiler();
+
+ //Incase a non-default compiler was specified and we could not find it in memory, fail.
+ if (compiler.Name == "ICompiler")
+ {
+ this._CompileMessages = new string[] { "Compilation Failed.", "Unable to locate the specified compiler of Type '" + Compiler + "'." };
+ return false;
+ }
+
+ //Get the compiler parameters.
+ CompilerParameters param = GetParameters();
+
+ //Create a Instance of the compiler, either custom or internal.
+ ICompiler com = (ICompiler)Activator.CreateInstance(compiler);
+
+ //Setup it's properties to match that of our CompileEngine.
+ com.AssemblyReferences = AssemblyReferences;
+ com.ScriptExtension = ScriptExtension;
+ com.CompilerOptions = this.CompilerOptions;
+
+ //Compile the script.
+ Boolean isSuccess = com.Compile(param, sourceFile);
+ HasErrors = !isSuccess;
+
+ //If the compilation failed, store all of the compiler errors
+ //into our _CompileMessages string.
+ if (!isSuccess)
+ {
+ List compilerMessages = new List();
+ foreach (String message in com.Results.Output)
+ {
+ compilerMessages.Add(message);
+ }
+
+ _CompileMessages = compilerMessages.ToArray();
+ return false;
+ }
+ else
+ {
+ //Compiling completed without error, so we need to save
+ //a reference to the compiled assembly.
+ CompiledAssembly = com.Results.CompiledAssembly;
+ return true;
+ }
+#else
+ return false;
+#endif
+ }
+
+ ///
+ /// Compiles the source code provided.
+ /// The compiler will compile the scripts using the compiler specified with the CompileEngine.Compiler Property.
+ ///
+ /// Returns true if compilation was completed without any errors.
+ public Boolean Compile(String[] sourceCode)
+ {
+#if WINDOWS_PC
+ //Get the compiler that the developer has selected.
+ //If the developer chooses a compiler that is not part of the engine, the GetCompiler() method
+ //will check all the currently loaded assemblies in memory for a custom compiler implementing
+ //the ICompiler interface.
+ Type compiler = GetCompiler();
+
+ //Incase a non-default compiler was specified and we could not find it in memory, fail.
+ if (compiler.Name == "ICompiler")
+ {
+ this._CompileMessages = new string[] { "Compilation Failed.", "Unable to locate the specified compiler of Type '" + Compiler + "'." };
+ return false;
+ }
+
+ //Get the compiler parameters.
+ CompilerParameters param = GetParameters();
+
+ //Create a Instance of the compiler, either custom or internal.
+ ICompiler com = (ICompiler)Activator.CreateInstance(compiler);
+
+ //Setup it's properties to match that of our CompileEngine.
+ com.AssemblyReferences = AssemblyReferences;
+ com.ScriptExtension = ScriptExtension;
+ com.CompilerOptions = this.CompilerOptions;
+
+ //Compile the scripts.
+ Boolean isSuccess = com.Compile(param, sourceCode);
+ HasErrors = !isSuccess;
+
+ //If the compilation failed, store all of the compiler errors
+ //into our _CompileMessages string.
+ if (!isSuccess)
+ {
+ List compilerMessages = new List();
+ foreach (String message in com.Results.Output)
+ {
+ compilerMessages.Add(message);
+ }
+
+ _CompileMessages = compilerMessages.ToArray();
+ return false;
+ }
+ else
+ {
+ //Compiling completed without error, so we need to save
+ //a reference to the compiled assembly.
+ CompiledAssembly = com.Results.CompiledAssembly;
+ return true;
+ }
+#else
+ return false;
+#endif
+ }
+#if WINDOWS_PC
+ ///
+ /// Gets compiler parameters that the compiler will be supplied with.
+ ///
+ ///
+ private CompilerParameters GetParameters()
+ {
+ //Setup some default parameters that will be used by the compilers.
+ CompilerParameters param = new CompilerParameters(this.AssemblyReferences.ToArray());
+ param.GenerateExecutable = false;
+ param.GenerateInMemory = true;
+
+ //Left out, Add as CompileEngine properties in the future.
+ //param.TreatWarningsAsErrors = true;
+ //param.WarningLevel = 0;
+ //param.IncludeDebugInformation = true;
+ return param;
+ }
+
+ ///
+ /// Gets the compiler that will be used during the compilation of the scripts.
+ /// If a custom compiler is used, then the method will check every assembly in memory
+ /// and find the custom one requested. If none are found, then it will return a new
+ /// Object of type ICompiler.
+ ///
+ ///
+ private Type GetCompiler()
+ {
+ Type compiler = typeof(ICompiler);
+
+ //Internal CSharpRaw compiler Type specified, so we'll use that.
+ if ((this.Compiler.ToLower() == "c#") || (this.Compiler.ToLower() == "csharp"))
+ {
+ compiler = typeof(CSharp);
+ return compiler;
+ }
+
+ //Build a collection of available compilers by scanning all the assemblies loaded in memory.
+ //If any of the assemblies contain a Type that uses the ICompiler interface, we will assume that the
+ //assembly is a add-on assembly for rScript, adding a new compiler to the CompileEngine.
+ //Only used if a non-internal compiler is specified
+ else
+ { //Non-internal compiler supplied, so loop through every assembly loaded in memory
+ foreach (Assembly a in _Assemblies)
+ {
+ Boolean isCompiler = false;
+
+ //Create an array of all Types within this assembly
+ Type[] types = a.GetTypes();
+
+ //Itterate through each Type; See if any implement the ICompiler interface.
+ foreach (Type t in a.GetTypes())
+ {
+ //If this Type implements ICompiler, then our compiler field needs to reference the Type.
+ if ((t.GetInterface("ICompiler") != null) && (t.Name.ToLower() == Compiler.ToLower()))
+ {
+ //compiler needs to reference this custom compiler Type.
+ compiler = t;
+ isCompiler = true;
+ break;
+ }
+ }
+
+ //If we found a matching compiler, then exit this loop.
+ if (isCompiler)
+ break;
+ }
+ }
+
+
+ return compiler;
+ }
+#endif
+ }
+}
\ No newline at end of file
diff --git a/MudEngine/WinPC_Engine/Scripting/ICompiler.cs b/MudEngine/WinPC_Engine/Scripting/ICompiler.cs
new file mode 100644
index 0000000..509ee7f
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Scripting/ICompiler.cs
@@ -0,0 +1,43 @@
+using System;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+
+namespace MudEngine.Scripting
+{
+ ///
+ /// Used to implement a wrapper for an existing compiler.
+ ///
+ public interface ICompiler
+ {
+#if WINDOWS_PC
+ CompilerResults Results { get; set; }
+ ///
+ /// The file extension used for the script files.
+ ///
+ String ScriptExtension { get; set; }
+
+ ///
+ /// Provides a collection of Assemblies that the compiler will add to its reference list.
+ ///
+ List AssemblyReferences { get; set; }
+
+ ///
+ /// Provides compiling options to various compilers, if they support this feature.
+ ///
+ Dictionary CompilerOptions { get; set; }
+
+ ///
+ /// Compiles the source files found within the scriptRepository directory matching the ICompiler.ScriptExtension
+ /// The Compiler defaults to the C# 4.0 compiler if none other is supplied via the ICompiler.CompilerOptions argument.
+ ///
+ /// Compiler Parameters that can be supplied to customize the compilation of the source.
+ /// Returns true if the compilation was completed without error.
+ Boolean Compile(CompilerParameters param, String scriptRepository);
+
+ Boolean Compile(CompilerParameters param, System.IO.FileInfo scriptFile);
+
+ Boolean Compile(CompilerParameters param, String[] scriptSource);
+
+#endif
+ }
+}
\ No newline at end of file
diff --git a/MudEngine/WinPC_Engine/Scripting/ScriptEnumerator.cs b/MudEngine/WinPC_Engine/Scripting/ScriptEnumerator.cs
new file mode 100644
index 0000000..94b4814
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Scripting/ScriptEnumerator.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using MudEngine.GameScripts;
+using MudEngine.Core;
+
+namespace MudEngine.Scripting
+{
+ internal class ScriptEnumerator : IEnumerator
+ {
+ public ScriptEnumerator(ObjectCollection objectManager)
+ {
+ this._ObjectCollection = objectManager;
+ }
+
+ public void Reset()
+ {
+ this._currentIndex = -1;
+ }
+
+ public BaseScript Current
+ {
+ get
+ {
+ if (this._currentIndex < 0)
+ return null;
+ else if (this._currentIndex > this._ObjectCollection.Length)
+ return null;
+ else
+ return this._ObjectCollection[this._currentIndex];
+ }
+ }
+
+ public void Dispose()
+ {
+ throw new NotImplementedException();
+ }
+
+ object System.Collections.IEnumerator.Current
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public bool MoveNext()
+ {
+ throw new NotImplementedException();
+ }
+
+ private Int32 _currentIndex = -1;
+ private ObjectCollection _ObjectCollection;
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Scripting/ScriptFactory.cs b/MudEngine/WinPC_Engine/Scripting/ScriptFactory.cs
new file mode 100644
index 0000000..a1a553f
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Scripting/ScriptFactory.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+
+using MudEngine.Core;
+using MudEngine.Game;
+using MudEngine.GameScripts;
+
+namespace MudEngine.Scripting
+{
+ public class ScriptFactory
+ {
+ //The assembly loaded that will be used.
+ private List _AssemblyCollection;
+
+#if WINDOWS_PC
+ ///
+ /// Constructor for a Windows PC Script Factory
+ ///
+ ///
+ public ScriptFactory(String assembly)
+ {
+ Assembly a;
+ _AssemblyCollection = new List();
+
+ //See if a file exists first with this assembly name.
+ if (File.Exists(assembly))
+ {
+ a = Assembly.Load(new AssemblyName(assembly));
+ }
+ //If not, then try and load it differently
+ else
+ {
+ a = Assembly.Load(assembly);
+ }
+
+ if (a == null)
+ return;
+
+ //Add the assembly to our assembly collection.
+ _AssemblyCollection.Add(a);
+ }
+
+ ///
+ /// Alternate Constructor for a Windows PC ScriptFactory
+ ///
+ ///
+ public ScriptFactory(Assembly assembly)
+ {
+ _AssemblyCollection = new List();
+ //Add the supplied assembly to our AssemblyCollection
+ _AssemblyCollection.Add(assembly);
+ }
+#endif
+ ///
+ /// Adds another assembly to the factories assembly collection.
+ ///
+ /// provides the name of the assembly, or file name that needs to be loaded.
+ public void AddAssembly(String assembly)
+ {
+ Assembly a;
+
+ //See if a file exists first with this assembly name.
+ if (File.Exists(assembly))
+ {
+ a = Assembly.Load(new AssemblyName(assembly));
+ }
+ //If not, then try and load it differently
+ else
+ {
+ a = Assembly.Load(assembly);
+ }
+
+ //Add the assembly to our assembly collection.
+ _AssemblyCollection.Add(a);
+ }
+
+ ///
+ /// Adds another assembly to the factories assembly collection.
+ ///
+ /// Provides a reference to the assembly that will be added to the collection.
+ public void AddAssembly (Assembly assembly)
+ {
+ //Add the supplied assembly to our AssemblyCollection
+ _AssemblyCollection.Add(assembly);
+ }
+
+ public BaseScript GetScript(String scriptName, StandardGame game)
+ {
+ Type script = typeof(Object);
+ Boolean foundScript = false;
+
+ if (_AssemblyCollection.Count == 0)
+ return new BaseScript(game, "New Object", String.Empty);
+
+ try
+ {
+#if WINDOWS_PC
+ foreach (Assembly a in _AssemblyCollection)
+ {
+ //The assembly can be null if accessing after a failed compilation.
+ if (a == null)
+ continue;
+
+ foreach (Type t in a.GetTypes())
+ {
+ if (t.Name == scriptName)
+ {
+ script = t;
+ foundScript = true;
+ break;
+ }
+ }
+
+ if (foundScript)
+ break;
+ }
+#elif WINDOWS_PHONE
+ foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
+ {
+ if (t.Name == scriptName)
+ {
+ script = t;
+ foundScript = true;
+ break;
+ }
+ }
+#endif
+ }
+ catch
+ {
+ throw new Exception("Error encounted during factory instancing of script " + scriptName + ".");
+ }
+
+ try
+ {
+ BaseScript obj = (BaseScript)Activator.CreateInstance(script, game, "New Object", String.Empty);
+ return obj;
+ }
+ catch
+ {
+ Logger.WriteLine("ERROR: Failed to locate and instance script (" + scriptName + ")");
+ return new BaseScript(game, "New Object", String.Empty);
+ }
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Scripting/ScriptObject.cs b/MudEngine/WinPC_Engine/Scripting/ScriptObject.cs
new file mode 100644
index 0000000..0141f53
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Scripting/ScriptObject.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Reflection;
+using System.Text;
+
+namespace sEngine.Scripting
+{
+ public class ScriptObject
+ {
+ public Object Instance { get; set; }
+
+ public ScriptObject(Object instance)
+ {
+ if (instance == null)
+ Instance = new Object();
+ else
+ Instance = instance;
+ }
+
+ ~ScriptObject()
+ {
+ //TODO: Add ability to call a Shutdown() method within this Instance.
+ Instance = null;
+ }
+
+ public void SetProperty(String propertyName, object propertyValue)
+ {
+ PropertyInfo propertyInfo = Instance.GetType().GetProperty(propertyName);
+
+ if (propertyValue is String)
+ {
+ if (propertyInfo.PropertyType.Name is String)
+ {
+ propertyInfo.SetValue(Instance, propertyValue, null);
+ }
+ }
+ }
+
+ public object GetProperty(String propertyName)
+ {
+ String[] tokens = propertyName.Split('.');
+ PropertyInfo previousProperty = Instance.GetType().GetProperty(tokens[0]);
+
+ return previousProperty.GetValue(Instance, null);
+ }
+
+#if WINDOWS_PC
+ public dynamic GetProperty()
+ {
+ return Instance;
+ }
+#endif
+
+ public object GetField(String propertyName)
+ {
+ String[] tokens = propertyName.Split('.');
+ FieldInfo previousField = Instance.GetType().GetField(tokens[0]);
+
+ return previousField.GetValue(Instance);
+ }
+
+#if WINDOWS_PC
+ public dynamic GetField()
+ {
+ return Instance;
+ }
+#endif
+
+ public Object InvokeMethod(String methodName)
+ {
+ return InvokeMethod(methodName, null);
+ }
+
+ public Object InvokeMethod(String methodName, params Object[] parameters)
+ {
+ MethodInfo method = Instance.GetType().GetMethod(methodName);
+
+ try
+ {
+ if (parameters == null || parameters.Length == 0)
+ return method.Invoke(Instance, null);
+ else
+ return method.Invoke(Instance, parameters);
+ }
+ catch
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("Error invoking method. Does the method exist?");
+ return sb.ToString();
+ }
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/WinPC_Engine.csproj b/MudEngine/WinPC_Engine/WinPC_Engine.csproj
index a389644..241b771 100644
--- a/MudEngine/WinPC_Engine/WinPC_Engine.csproj
+++ b/MudEngine/WinPC_Engine/WinPC_Engine.csproj
@@ -51,11 +51,13 @@
+
-
+
+
@@ -63,10 +65,15 @@
+
+
+
+
+
+
-