diff --git a/MudEngine/MudEngine.sln b/MudEngine/MudEngine.sln
new file mode 100644
index 0000000..70d831e
--- /dev/null
+++ b/MudEngine/MudEngine.sln
@@ -0,0 +1,54 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinPC_Server", "WinPC_Server\WinPC_Server.csproj", "{9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinPC_Engine", "WinPC_Engine\WinPC_Engine.csproj", "{27C84625-1D4A-4DBF-9770-46D535506485}"
+EndProject
+Global
+ GlobalSection(TeamFoundationVersionControl) = preSolution
+ SccNumberOfProjects = 3
+ SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+ SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs03
+ SccLocalPath0 = .
+ SccProjectUniqueName1 = WinPC_Engine\\WinPC_Engine.csproj
+ SccProjectName1 = WinPC_Engine
+ SccLocalPath1 = WinPC_Engine
+ SccProjectUniqueName2 = WinPC_Server\\WinPC_Server.csproj
+ SccProjectName2 = WinPC_Server
+ SccLocalPath2 = WinPC_Server
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Debug|x86.ActiveCfg = Debug|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Debug|x86.Build.0 = Debug|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Release|Any CPU.ActiveCfg = Release|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Release|Mixed Platforms.Build.0 = Release|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Release|x86.ActiveCfg = Release|x86
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}.Release|x86.Build.0 = Release|x86
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Release|Any CPU.Build.0 = Release|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {27C84625-1D4A-4DBF-9770-46D535506485}.Release|x86.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/MudEngine/MudEngine.vssscc b/MudEngine/MudEngine.vssscc
new file mode 100644
index 0000000..794f014
--- /dev/null
+++ b/MudEngine/MudEngine.vssscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/MudEngine/WinPC_Engine/Core/BaseCommand.cs b/MudEngine/WinPC_Engine/Core/BaseCommand.cs
new file mode 100644
index 0000000..c60dee5
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/BaseCommand.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+
+using MudEngine.Game.Characters;
+using MudEngine.Core.Interface;
+
+namespace MudEngine.Core
+{
+ public abstract class BaseCommand : ICommand
+ {
+ ///
+ /// Gets or Sets a collection of help topics related to this command.
+ ///
+ [Browsable(false)]
+ public List Help { get; set; }
+
+ public BaseCommand()
+ {
+ Help = new List();
+ this.Name = this.GetType().Name.Substring("Command".Length);
+ }
+
+ ///
+ /// Executes the command for the character supplied.
+ ///
+ ///
+ ///
+ public abstract void Execute(string command, StandardCharacter character);
+
+ public string Name {get;set;}
+
+ public string Description
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ set
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Core/CommandSystem.cs b/MudEngine/WinPC_Engine/Core/CommandSystem.cs
new file mode 100644
index 0000000..befd323
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/CommandSystem.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+
+using MudEngine.Core.Interface;
+using MudEngine.Game.Characters;
+
+namespace MudEngine.Core
+{
+ public class CommandSystem
+ {
+ public static Dictionary Commands
+ {
+ get
+ {
+ if (_Commands == null)
+ _Commands = new Dictionary();
+ return _Commands;
+ }
+ private set
+ {
+ _Commands = value;
+ }
+ }
+ private static Dictionary _Commands;
+
+ public Dictionary CommandCollection { get; private set; }
+
+ public CommandSystem(Dictionary commands)
+ {
+ this.CommandCollection = new Dictionary();
+ this.CommandCollection = commands;
+
+ //Handled by the StandardGame class now.
+ //LoadCommands();
+ }
+
+ public List GetCommands()
+ {
+ List collection = new List();
+
+ foreach (ICommand c in CommandSystem.Commands.Values)
+ collection.Add(c);
+
+ return collection;
+ }
+
+ public ICommand GetCommand(string command)
+ {
+ foreach (ICommand c in CommandSystem.Commands.Values)
+ {
+ if (c.Name.ToLower() == command.ToLower())
+ return c;
+ }
+
+ return null;
+ }
+
+ public bool IsValidCommand(string command)
+ {
+ if (CommandSystem.Commands.ContainsKey(command))
+ return true;
+ else
+ return false;
+ }
+
+ public void Execute(string command, StandardCharacter character)
+ {
+ string key = command.Insert(0, "Command");
+
+ foreach (string k in CommandSystem.Commands.Keys)
+ {
+ if (key.ToLower().Contains(k.ToLower()))
+ {
+ ICommand cmd = CommandSystem.Commands[k];
+ try
+ {
+ cmd.Execute(command, character);
+ }
+ catch (Exception ex)
+ {
+ Logger.WriteLine("Error: " + ex.Message);
+ Console.WriteLine("Error: " + ex.Message);
+ }
+
+ return;
+ }
+ }
+
+ //TODO: Inform player that this was not a valid command.
+ }
+
+ public static void LoadCommands()
+ {
+ LoadCommandLibrary(Assembly.GetExecutingAssembly(), true);
+ }
+
+ public static void LoadCommandLibrary(Assembly commandLibrary)
+ {
+ LoadCommandLibrary(commandLibrary, true);
+ }
+
+ public static void LoadCommandLibrary(Assembly commandLibrary, bool purgeLoadedCommands)
+ {
+ if (purgeLoadedCommands)
+ PurgeCommands();
+
+ if (commandLibrary == null)
+ return;
+
+ foreach (Type type in commandLibrary.GetTypes())
+ {
+ //All commands implement the ICommand interface.
+ //If that interface is not present on this Type, skip and go to the next one.
+ if (type.GetInterface("ICommand") == null)
+ continue;
+ else if (type.IsAbstract)
+ continue;
+
+ ICommand cmd = (ICommand)Activator.CreateInstance(type);
+
+ if (cmd != null)
+ {
+ //Fail safe measures. Ensure that we always have a name assigned to the commands.
+ if ((cmd.Name == "") || (cmd.Name == null))
+ cmd.Name = cmd.GetType().Name.ToLower();
+ else
+ cmd.Name = cmd.Name.ToLower(); //Commands are always stored in lower case.
+
+ if (Commands.ContainsKey(cmd.Name))
+ continue; //No overriding supported. Skip this command.
+
+ //Everything checks out ok. Add the command to our collection.
+ Commands.Add(cmd.Name, cmd);
+ }
+ }
+ }
+
+ public static void PurgeCommands()
+ {
+ Commands.Clear();
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Core/Interfaces/ICommand.cs b/MudEngine/WinPC_Engine/Core/Interfaces/ICommand.cs
new file mode 100644
index 0000000..866fe55
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/Interfaces/ICommand.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using MudEngine.Game.Characters;
+
+namespace MudEngine.Core.Interface
+{
+ public interface ICommand
+ {
+ string Name { get; set; }
+ string Description { get; set; }
+ List Help { get; set; }
+
+ void Execute(string command, StandardCharacter character);
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Core/Interfaces/IGameComponent.cs b/MudEngine/WinPC_Engine/Core/Interfaces/IGameComponent.cs
new file mode 100644
index 0000000..8c61b7b
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/Interfaces/IGameComponent.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.Core.Interfaces
+{
+ ///
+ /// Provides an API for scripts that need to be Initialized and Destroyed during gameplay.
+ ///
+ public interface IGameComponent
+ {
+ ///
+ /// Method for initializing any code that must be executed prior to anything else.
+ ///
+ void Initialize();
+
+ ///
+ /// Method for destroying any resources that the class might be using.
+ ///
+ void Destroy();
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Core/Interfaces/INetworked.cs b/MudEngine/WinPC_Engine/Core/Interfaces/INetworked.cs
new file mode 100644
index 0000000..a883960
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/Interfaces/INetworked.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.Core.Interfaces
+{
+ ///
+ /// Public API for scripts that take advantage of the engines Networking
+ ///
+ public interface INetworked
+ {
+ ///
+ /// Method used for sending messages from the server to the object.
+ ///
+ ///
+ void SendMessage(String message);
+
+ ///
+ /// Method for disconnecting the object from the server.
+ ///
+ void Disconnect();
+
+ ///
+ /// Method for connecting a object to the server.
+ ///
+ void Connect();
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Core/Interfaces/ISavable.cs b/MudEngine/WinPC_Engine/Core/Interfaces/ISavable.cs
new file mode 100644
index 0000000..fce1efd
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/Interfaces/ISavable.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.Core.Interfaces
+{
+ ///
+ /// Public API for classes that need to be saved during runtime.
+ ///
+ public interface ISavable
+ {
+ ///
+ /// Objects filename.
+ ///
+ String Filename { get; set; }
+
+ ///
+ /// Save method for dumping the object to physical file.
+ ///
+ ///
+ void Save(String path);
+
+ ///
+ /// Load method for retrieving saved data from file.
+ ///
+ /// Filename is required complete with Path since this object does not exist yet (can not get filename from non-existing object)
+ void Load(String filename);
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Core/Interfaces/IUpdatable.cs b/MudEngine/WinPC_Engine/Core/Interfaces/IUpdatable.cs
new file mode 100644
index 0000000..7b52ce7
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/Interfaces/IUpdatable.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.Core.Interfaces
+{
+ ///
+ /// Public API for classes that need to be updated constantly.
+ ///
+ public interface IUpdatable
+ {
+ void Update();
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Core/Logger.cs b/MudEngine/WinPC_Engine/Core/Logger.cs
new file mode 100644
index 0000000..5df69f1
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Core/Logger.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.IO.IsolatedStorage;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.Core
+{
+ ///
+ /// Public Engine Logging Class.
+ ///
+ public static class Logger
+ {
+ ///
+ /// The Log Filename for the engine log.
+ ///
+ public static string LogFilename { get; set; }
+
+ ///
+ /// Gets or Sets if the Logger is enabled or disabled.
+ ///
+ public static Boolean Enabled { get; set; }
+
+ ///
+ /// Gets or Sets if the logger will output it's information to the Console.
+ ///
+ public static Boolean ConsoleOutPut { get; set; }
+
+ ///
+ /// Clears the queued log messages from cache
+ ///
+ public static void ClearLog()
+ {
+ //If the log file exists, delete it.
+ if (String.IsNullOrEmpty(LogFilename))
+ LogFilename = "Engine.Log";
+
+ if (System.IO.File.Exists(LogFilename))
+ System.IO.File.Delete(LogFilename);
+
+ //Clear the cache.
+ _Messages.Clear();
+ }
+
+ ///
+ /// Writes a single line to the engine log file.
+ ///
+ ///
+ public static void WriteLine(String message)
+ {
+ //Only write to log if enabled.
+ if (!Enabled)
+ return;
+
+ //Make sure we have a valid filename
+ if (String.IsNullOrEmpty(LogFilename))
+ LogFilename = "Engine.Log";
+
+ //Ensure that the log messages cache is not null
+ if (_Messages == null)
+ _Messages = new List();
+
+ //Get the current time and format it
+ String Time = DateTime.Now.ToString("h:mm:ss:ff tt");
+
+ //Output to console if enabled.
+ if (ConsoleOutPut)
+ Console.WriteLine(Time + ": " + message);
+
+ //Try to write the message to the log file.
+ try
+ {
+ using (System.IO.StreamWriter file = new System.IO.StreamWriter(LogFilename, true))
+ {
+ //Write the message to file
+ file.WriteLine(Time + ": " + message);
+ //Add it to the messages cache.
+ _Messages.Add(Time + ": " + message);
+ }
+ }
+ catch
+ {
+ throw new Exception("Unable to write message (" + message + ") to log file (" + LogFilename + ").");
+ }
+ }
+
+ ///
+ /// Returns an array of messages that have been queued in the log cache.
+ ///
+ ///
+ public static String[] GetMessages()
+ {
+ if (_Messages == null)
+ return new string[0];
+ else
+ return _Messages.ToArray();
+ }
+
+ private static List _Messages;
+ }
+}
diff --git a/MudEngine/WinPC_Engine/DAL/DataPaths.cs b/MudEngine/WinPC_Engine/DAL/DataPaths.cs
new file mode 100644
index 0000000..18d4ea2
--- /dev/null
+++ b/MudEngine/WinPC_Engine/DAL/DataPaths.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.DAL
+{
+ ///
+ /// Contains the paths for the engines file storage.
+ ///
+ public struct DataPaths
+ {
+ ///
+ /// Path to the engines Script directory
+ ///
+ public String Scripts { get; set; }
+
+ ///
+ /// Path to the engines Environment files.
+ ///
+ public String Environments { get; set; }
+
+ ///
+ /// Path to the engines saved objects (Equipment etc).
+ ///
+ public String Objects { get; set; }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/DAL/XmlParser.cs b/MudEngine/WinPC_Engine/DAL/XmlParser.cs
new file mode 100644
index 0000000..4e18fb0
--- /dev/null
+++ b/MudEngine/WinPC_Engine/DAL/XmlParser.cs
@@ -0,0 +1,12 @@
+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/CharacterRoles.cs b/MudEngine/WinPC_Engine/Game/Characters/CharacterRoles.cs
new file mode 100644
index 0000000..08c9fdd
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Game/Characters/CharacterRoles.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.Game.Characters
+{
+ ///
+ /// Various server roles that a character can have.
+ ///
+ public enum CharacterRoles
+ {
+ Admin,
+ Immortal,
+ GM,
+ QuestGiver,
+ Player,
+ NPC
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Game/Characters/CharacterStats.cs b/MudEngine/WinPC_Engine/Game/Characters/CharacterStats.cs
new file mode 100644
index 0000000..d93c66f
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Game/Characters/CharacterStats.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.Game.Characters
+{
+ ///
+ /// Stats that are used by the Character
+ ///
+ public struct CharacterStats
+ {
+ public int Strength { get; set; }
+ public int Dexterity { get; set; }
+ public int Constitution { get; set; }
+ public int Intelligence { get; set; }
+ public int Wisdom { get; set; }
+ public int Charisma { get; set; }
+ public int Experience { get; set; }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Game/Characters/StandardCharacter.cs b/MudEngine/WinPC_Engine/Game/Characters/StandardCharacter.cs
new file mode 100644
index 0000000..1ddf003
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Game/Characters/StandardCharacter.cs
@@ -0,0 +1,199 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.IO;
+using System.Text;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+using MudEngine.GameScripts;
+using MudEngine.Core.Interfaces;
+using MudEngine.Networking;
+using MudEngine.Core;
+
+namespace MudEngine.Game.Characters
+{
+ ///
+ /// Standard Character class used by all character based objects
+ ///
+ public class StandardCharacter : BaseScript, INetworked, ISavable, IUpdatable, IGameComponent
+ {
+ ///
+ /// Gets a reference to the currently active game.
+ ///
+ public StandardGame Game { get; private set; }
+
+ ///
+ /// Gets what this Characters role on the server is.
+ ///
+ public CharacterRoles Role { get; protected set; }
+
+ ///
+ /// Gets what this characters stats are.
+ ///
+ public CharacterStats Stats { get; protected set; }
+
+ //TODO: Should be Private/Protected?
+ public String Password { get; set; }
+
+ ///
+ /// Flags this object as non-movable in the world.
+ ///
+ public Boolean Immovable { get; set; }
+
+ //TODO: Add current location to characters
+ //public IEnvironment CurrentLocation
+
+ protected CommandSystem Commands { get; private set; }
+
+ public StandardCharacter(String name, String description, StandardGame game) : base(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)
+ {
+ this._Connection = connection;
+
+ this._Reader = new StreamReader(new NetworkStream(this._Connection, false));
+ this._Writer = new StreamWriter(new NetworkStream(this._Connection, true));
+
+ this._Writer.AutoFlush = true; //Flushes the stream automatically.
+ this._InitialMessage = true; //Strips Telnet client garbage text from initial message sent from client.
+ }
+
+ internal void ExecuteCommand(string command)
+ {
+ //Process commands here.
+ if (this._InitialMessage)
+ {
+ command = this.CleanString(command);
+ this._InitialMessage = false;
+ }
+
+ this.Commands.Execute(command, this);
+ }
+
+ public void SendMessage(string message)
+ {
+ lock (this)
+ {
+ _Writer.WriteLine(message);
+ }
+ }
+
+ public void Disconnect()
+ {
+ Console.WriteLine("Disconnecting...");
+
+ //Close our currently open socket.
+ this._Connection.Close();
+
+ //Remove this character from the Connection Manager
+ ConnectionManager.RemoveConnection(this);
+ Console.WriteLine("Disconnect Complete.");
+
+ //Stop the Update() thread.
+ this._LoopThread.Abort();
+ }
+
+ public void Connect()
+ {
+ _LoopThread = new Thread(Update);
+ _LoopThread.Start();
+
+ this.SendMessage("");
+ OnConnectEvent();
+ }
+
+ public void Update()
+ {
+ try
+ {
+ while (this.Game.Enabled)
+ {
+ _Writer.Flush();
+ String line = _Reader.ReadLine();
+ ExecuteCommand(line);
+ }
+ }
+ catch
+ {
+ }
+ finally
+ {
+ this.Disconnect();
+ }
+ }
+
+ String CleanString(string line)
+ {
+ if ((!String.IsNullOrEmpty(line)) && (line.Length > 0))
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder(line.Length);
+ foreach (char c in line)
+ {
+ if (char.IsSymbol(c)) continue;
+
+ sb.Append(char.IsControl(c) ? ' ' : c);
+ }
+ String newLine = sb.ToString().Trim().Substring(2).Trim();
+ return newLine;
+ }
+ else
+ return String.Empty;
+ }
+
+ public delegate void OnConnectHandler();
+ public event OnConnectHandler OnConnectEvent;
+ public void OnConnect()
+ {
+ _Writer.WriteLine(this.Game.Server.MOTD);
+ }
+
+ private Socket _Connection;
+ private Thread _LoopThread;
+ private StreamReader _Reader;
+ private StreamWriter _Writer;
+ private Boolean _InitialMessage;
+
+ public string Filename
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ set
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public void Save(string path)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Load(string filename)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Initialize()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Destroy()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Game/Environment/TravelDirections.cs b/MudEngine/WinPC_Engine/Game/Environment/TravelDirections.cs
new file mode 100644
index 0000000..4cfb3c7
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Game/Environment/TravelDirections.cs
@@ -0,0 +1,83 @@
+using System;
+
+namespace MudEngine.Game.Environment
+{
+ //Available directions that the character can travel in the world.
+ [System.Flags]
+ public enum AvailableTravelDirections : uint
+ {
+ None = 0,
+ North = 1,
+ South = 2,
+ East = 4,
+ West = 8,
+ Up = 16,
+ Down = 32,
+ Northeast = North | East,
+ Northwest = North | West,
+ Southeast = South | East,
+ Southwest = South | West
+ }
+
+ public static class TravelDirections
+ {
+ ///
+ /// Returns a direction that is reversed from what was supplied.
+ ///
+ ///
+ ///
+ public static AvailableTravelDirections GetReverseDirection(AvailableTravelDirections Direction)
+ {
+ switch (Direction)
+ {
+ case AvailableTravelDirections.North:
+ return AvailableTravelDirections.South;
+ case AvailableTravelDirections.South:
+ return AvailableTravelDirections.North;
+ case AvailableTravelDirections.East:
+ return AvailableTravelDirections.West;
+ case AvailableTravelDirections.West:
+ return AvailableTravelDirections.East;
+ case AvailableTravelDirections.Up:
+ return AvailableTravelDirections.Down;
+ case AvailableTravelDirections.Down:
+ return AvailableTravelDirections.Up;
+ case AvailableTravelDirections.Northeast:
+ return AvailableTravelDirections.Southwest;
+ case AvailableTravelDirections.Southwest:
+ return AvailableTravelDirections.Northeast;
+ case AvailableTravelDirections.Northwest:
+ return AvailableTravelDirections.Southeast;
+ case AvailableTravelDirections.Southeast:
+ return AvailableTravelDirections.Northwest;
+ default:
+ return AvailableTravelDirections.None;
+ }
+ }
+
+ ///
+ /// Returns a enum value that matches that of the string supplied.
+ ///
+ ///
+ ///
+ public static AvailableTravelDirections GetTravelDirectionValue(String Direction)
+ {
+ //Blow all of the available values up into an array.
+ Array values = Enum.GetValues(typeof(AvailableTravelDirections));
+
+ //Loop through each available value, converting it into a string.
+ foreach (Int32 value in values)
+ {
+ //Get the string representation of the current value
+ String displayName = Enum.GetName(typeof(AvailableTravelDirections), value);
+
+ //Check if this value matches that of the supplied one.
+ //If so, return it as a enum
+ if (displayName.ToLower() == Direction.ToLower())
+ return (AvailableTravelDirections)Enum.Parse(typeof(AvailableTravelDirections), displayName);
+ }
+
+ return AvailableTravelDirections.None;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MudEngine/WinPC_Engine/Game/StandardGame.cs b/MudEngine/WinPC_Engine/Game/StandardGame.cs
new file mode 100644
index 0000000..d2d681a
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Game/StandardGame.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+
+using MudEngine.Networking;
+using MudEngine.Core;
+
+namespace MudEngine.Game
+{
+ public class StandardGame
+ {
+ public String Name { get; set; }
+
+ public String Website { get; set; }
+
+ public String Description { get; set; }
+
+ public String Version { get; set; }
+
+ public Boolean HiddenRoomNames { get; set; }
+
+ public Boolean Multiplayer { get; set; }
+
+ public Int32 MaximumPlayers { get; set; }
+
+ public Int32 MaxQueueSize { get; set; }
+
+ public Int32 MinimumPasswordSize { get; set; }
+
+ public Boolean AutoSave { get; set; }
+
+ public Boolean Enabled { get; private set; }
+
+ public Boolean Debugging { get; set; }
+
+ public Server Server { get; protected set; }
+
+ public StandardGame(String name) : this(name, 4000)
+ {
+ }
+
+ public StandardGame(String name, Int32 port)
+ {
+ Logger.WriteLine("Initializing Standard Mud Game");
+ this.Name = name;
+ this.Website = "http://scionwest.net";
+ this.Description = "A sample Mud game created using the Mud Designer kit.";
+ this.Version = "1.0";
+ this.Multiplayer = true;
+ this.MaximumPlayers = 50;
+ this.MinimumPasswordSize = 8;
+ this.MaxQueueSize = 20;
+ this.AutoSave = true;
+
+ //Setup our server.
+ this.Server = new Server(port);
+
+ this.Server.Port = port;
+ }
+
+ public Boolean Start()
+ {
+ Logger.WriteLine("Starting up Standard Game");
+
+ //Instance Script Engine
+
+ //Compile any scripts
+
+ //Load our Commands
+ CommandSystem.LoadCommands();
+
+ //Load World
+
+ //Start our server.
+ this.Server.Start(this);
+
+ //If the server started without error, flag the Game as enabled.
+ if (this.Server.Enabled)
+ this.Enabled = true;
+
+ return this.Enabled;
+ }
+
+ public void Stop()
+ {
+ //Save the world.
+
+ this.Server.Stop();
+
+ this.Enabled = false;
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/GameScripts/BaseScript.cs b/MudEngine/WinPC_Engine/GameScripts/BaseScript.cs
new file mode 100644
index 0000000..3f59904
--- /dev/null
+++ b/MudEngine/WinPC_Engine/GameScripts/BaseScript.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+
+namespace MudEngine.GameScripts
+{
+ public class BaseScript
+ {
+ public String Name { get; set; }
+
+ public String ID { get; set; }
+
+ public String Description { get; set; }
+
+ public BaseScript(String name, String description)
+ {
+ this.ID = Guid.NewGuid().ToString();
+ }
+
+ public override string ToString()
+ {
+ if (String.IsNullOrEmpty(this.Name))
+ return this.GetType().Name + " without Name";
+ else
+ return this.Name;
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/GameScripts/Commands/CommandSay.cs b/MudEngine/WinPC_Engine/GameScripts/Commands/CommandSay.cs
new file mode 100644
index 0000000..cd38bf2
--- /dev/null
+++ b/MudEngine/WinPC_Engine/GameScripts/Commands/CommandSay.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using MudEngine.Core.Interface;
+using MudEngine.Game;
+using MudEngine.Game.Characters;
+using MudEngine.Networking;
+
+namespace MudEngine.GameScripts.Commands
+{
+ public class CommandSay : ICommand
+ {
+ public string Name { get; set; }
+
+ public string Description { get; set; }
+
+ public List Help { get; set; }
+
+ public CommandSay()
+ {
+ this.Name = "Say";
+ this.Description = "Chat command that allows objects to communicate.";
+ }
+
+ public void Execute(string command, StandardCharacter character)
+ {
+ //Grab a reference to the character for simplifying access.
+ StandardGame game = character.Game;
+ //Remove the command "Say " from the string so we only have it's message
+ String message = command.Substring(3).Trim();
+
+ //Loop through each character on the server and broadcast the message.
+ //TODO: This should only broadcast to characters that are in the same Environment.
+ foreach (StandardCharacter c in ConnectionManager.Connections)
+ {
+ //Only broadcast this message to those that are not the broadcastor.
+ if (c != character)
+ c.SendMessage(character.ToString() + " says: " + message);
+ }
+
+ //Send a different copy of the message to the broadcastor.
+ character.SendMessage("You say: " + message);
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Networking/ConnectionManager.cs b/MudEngine/WinPC_Engine/Networking/ConnectionManager.cs
new file mode 100644
index 0000000..a923c23
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Networking/ConnectionManager.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+using MudEngine.Game;
+using MudEngine.Game.Characters;
+
+namespace MudEngine.Networking
+{
+ public static class ConnectionManager
+ {
+ //Collection of currently connected players.
+ public static List Connections { get; set; }
+
+ ///
+ /// Creates a new character for the player and sets it up on the server.
+ ///
+ ///
+ ///
+ public static void AddConnection(StandardGame game, Socket connection)
+ {
+ //Exception checking.
+ if (Connections == null)
+ Connections = new List();
+
+ //Instance a new character and provide it with the Socket.
+ StandardCharacter character = new StandardCharacter("New Player", "New networked client.", game, connection);
+
+ //Add it to the Connections collection
+ Connections.Add(character);
+
+ //Invoke the Characters Server connection method
+ character.Connect();
+ }
+
+ ///
+ /// Removes the specified player character from the server.
+ ///
+ ///
+ public static void RemoveConnection(StandardCharacter character)
+ {
+ Connections.Remove(character);
+ }
+
+ ///
+ /// Disconnects all of the currently connected clients.
+ ///
+ public static void DisconnectAll()
+ {
+ if (Connections == null)
+ return;
+
+ foreach (StandardCharacter character in Connections)
+ {
+ character.Disconnect();
+ }
+ Connections.Clear();
+ }
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Networking/Server.cs b/MudEngine/WinPC_Engine/Networking/Server.cs
new file mode 100644
index 0000000..69ff723
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Networking/Server.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+using MudEngine.Core;
+using MudEngine.Core.Interfaces;
+using MudEngine.Game;
+using MudEngine.Game.Characters;
+
+namespace MudEngine.Networking
+{
+ [Category("Networking")]
+ public class Server
+ {
+ [Category("Networking")]
+ [Description("The name of this server")]
+ public String Name { get; set; }
+
+ [Category("Networking")]
+ public Int32 Port { get; set; }
+
+ [Category("Networking")]
+ [Description("The Message Of The Day that is presented to users when they connect.")]
+ public String MOTD { get; set; }
+
+ [Category("Networking")]
+ [Description("Maximum number of people that can connect and play on this server at any time.")]
+ public Int32 MaxConnections { get; set; }
+
+ [Category("Networking")]
+ [Description("Maximum number of poeple that can be queued for connection.")]
+ public Int32 QueuedConnectionLimit { get; set; }
+
+ [Browsable(false)]
+ public Boolean Enabled { get; private set; }
+
+ ///
+ /// Sets up a server on the specified port.
+ ///
+ ///
+ ///
+ public Server(Int32 port)
+ {
+ Logger.WriteLine("Initializing Mud Server Settings");
+ this.Port = port;
+ this.MaxConnections = 50;
+ this.QueuedConnectionLimit = 20;
+ this.Name = "New Server";
+ this.MOTD = "Welcome to a sample Mud Engine game server!";
+
+ this._Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ this._Server.Bind(new IPEndPoint(IPAddress.Any, this.Port));
+ }
+
+ ///
+ /// Starts the game server. It will listen on a different thread of incoming connections
+ ///
+ public void Start(StandardGame game)
+ {
+ //Start the server.
+ Logger.WriteLine("Starting Mud Server.");
+
+ //Start listening for connections
+ this._Server.Listen(this.QueuedConnectionLimit);
+
+ //Launch the new connections listener on a new thread.
+ this._ConnectionPool = new Thread(AcceptConnection);
+ this._ConnectionPool.Start();
+
+ //Flag the server as enabled.
+ this.Enabled = true;
+
+ //Save a reference to the currently active game
+ this._Game = game;
+
+ Logger.WriteLine("Server started.");
+ }
+
+ public void Stop()
+ {
+ //Flag the server as disabled.
+ this.Enabled = false;
+
+ //Stop the thread from listening for accepting new conections
+ this._ConnectionPool.Abort();
+
+ //Disconnect all of the currently connected clients.
+ ConnectionManager.DisconnectAll();
+
+ //Stop the server.
+ this._Server.Close();
+ }
+
+ private void AcceptConnection()
+ {
+ //While the server is enabled, constantly check for new connections.
+ while (this.Enabled)
+ {
+ //Grab the new connection.
+ Socket incomingConnection = this._Server.Accept();
+
+ //Send it to the Connection Manager so a Character can be instanced.
+ ConnectionManager.AddConnection(this._Game, incomingConnection);
+ }
+ }
+
+ private Socket _Server;
+ private Thread _ConnectionPool;
+ private StandardGame _Game;
+ }
+}
diff --git a/MudEngine/WinPC_Engine/Properties/AssemblyInfo.cs b/MudEngine/WinPC_Engine/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b992c9d
--- /dev/null
+++ b/MudEngine/WinPC_Engine/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WinPC_Engine")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("WinPC_Engine")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8a61b00d-f6fb-4bdf-9253-531039ada2cb")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/MudEngine/WinPC_Engine/WinPC_Engine.csproj b/MudEngine/WinPC_Engine/WinPC_Engine.csproj
new file mode 100644
index 0000000..5b9e4a7
--- /dev/null
+++ b/MudEngine/WinPC_Engine/WinPC_Engine.csproj
@@ -0,0 +1,80 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {27C84625-1D4A-4DBF-9770-46D535506485}
+ Library
+ Properties
+ MudEngine
+ MudEnginePC
+ v4.0
+ 512
+ SAK
+ SAK
+ SAK
+ SAK
+
+
+ true
+ full
+ false
+ bin\Debug\
+ TRACE;DEBUG;WINDOWS_PC
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MudEngine/WinPC_Engine/WinPC_Engine.csproj.vspscc b/MudEngine/WinPC_Engine/WinPC_Engine.csproj.vspscc
new file mode 100644
index 0000000..feffdec
--- /dev/null
+++ b/MudEngine/WinPC_Engine/WinPC_Engine.csproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/MudEngine/WinPC_Server/Program.cs b/MudEngine/WinPC_Server/Program.cs
new file mode 100644
index 0000000..866e429
--- /dev/null
+++ b/MudEngine/WinPC_Server/Program.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+using MudEngine.Game;
+using MudEngine.Core;
+
+namespace SimpleMUD
+{
+ public class ServerInput
+ {
+ public String Message;
+
+ public ServerInput()
+ {
+ Message = String.Empty;
+ }
+
+ public void GetInput()
+ {
+ while (true)
+ {
+ Console.WriteLine("Enter a test message: ");
+ Message = Console.ReadLine();
+ }
+ }
+ }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Logger.LogFilename = "StandardGame.Log";
+ Logger.Enabled = true;
+ Logger.ConsoleOutPut = true;
+
+ StandardGame game = new StandardGame("Sample Game");
+ game.Start();
+
+ Boolean msgReturn = false;
+ ServerInput input = new ServerInput();
+
+ Thread inputThread = new Thread(input.GetInput);
+ inputThread.Start();
+
+ while (game.Enabled)
+ {
+ if (input.Message.Equals("exit"))
+ {
+ game.Stop();
+ }
+ else if (input.Message.Equals("test") && (msgReturn == false))
+ {
+ Console.WriteLine("Message Works");
+ input.Message = String.Empty;
+ }
+ }
+
+ inputThread.Abort();
+ }
+ }
+}
\ No newline at end of file
diff --git a/MudEngine/WinPC_Server/Properties/AssemblyInfo.cs b/MudEngine/WinPC_Server/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..54fd0f8
--- /dev/null
+++ b/MudEngine/WinPC_Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WinPC_Server")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("WinPC_Server")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a627d239-f19d-4b18-8779-b7312aeb68b3")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/MudEngine/WinPC_Server/WinPC_Server.csproj b/MudEngine/WinPC_Server/WinPC_Server.csproj
new file mode 100644
index 0000000..5c46f98
--- /dev/null
+++ b/MudEngine/WinPC_Server/WinPC_Server.csproj
@@ -0,0 +1,69 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {9F118DC3-CB8E-45FB-ABA5-10D50A6CD3F1}
+ Exe
+ Properties
+ WinPC_Server
+ WinPC_Server
+ v4.0
+ Client
+ 512
+ SAK
+ SAK
+ SAK
+ SAK
+
+
+ x86
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {27C84625-1D4A-4DBF-9770-46D535506485}
+ WinPC_Engine
+
+
+
+
+
\ No newline at end of file
diff --git a/MudEngine/WinPC_Server/WinPC_Server.csproj.vspscc b/MudEngine/WinPC_Server/WinPC_Server.csproj.vspscc
new file mode 100644
index 0000000..feffdec
--- /dev/null
+++ b/MudEngine/WinPC_Server/WinPC_Server.csproj.vspscc
@@ -0,0 +1,10 @@
+""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}