using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using MudEngine.Networking;
using MudEngine.Core;
using MudEngine.Game.Characters;
using MudEngine.DAL;
using MudEngine.Game.Environment;
using MudEngine.Scripting;
using MudEngine.Core.Interfaces;
namespace MudEngine.Game
{
///
/// StandardGame will be the base of all Mud Games created with the engine.
/// It manages all of the game components including the Server and the Game World.
///
public class StandardGame
{
///
/// Gets or Sets the Name of this game.
///
public String Name { get; set; }
///
/// Gets or Sets the website where this game can be played at.
///
public String Website { get; set; }
///
/// Gets or Sets the Description of this game. This is often displayed upon first connection.
/// Note that this is displayed BEFORE the Servers MOTD.
///
public String Description { get; set; }
///
/// Gets or Sets the Version of this game.
///
public String Version { get; set; }
///
/// Gets or Sets if Room Names will be shown to the player each time they travel to a new Room.
///
public Boolean HiddenRoomNames { get; set; }
///
/// Gets or Sets if this Game is currently being played on a Server
///
public Boolean Multiplayer { get; set; }
///
/// Gets or Sets the minimum password size required for user account passwords
///
public Int32 MinimumPasswordSize { get; set; }
///
/// Get or Sets if the game will automatically save the world. For servers with poor specifications, this can be disabled to
/// help with performance. Manually saving the world will be required.
///
public Boolean AutoSave { get; set; }
///
/// Gets if the game is currently running or not.
///
public Boolean Enabled { get; protected set; }
///
/// Gets or Sets if the game is in debug more or not.
///
public Boolean Debugging { get; set; }
///
/// Gets a reference to the currently running Server.
///
public Server Server { get; protected set; }
///
/// Gets a reference to the current Game World
///
public World World { get; protected set; }
///
/// Gets or Sets the paths that content is saved to.
///
public DataPaths SavePaths { get; set; }
public ScriptFactory ScriptFactory { get; set; }
///
/// StandardGame constructor. If no Port number is provided, 4000 is used.
///
///
public StandardGame(String name) : this(name, 4000)
{
}
///
/// StandardGame constructor.
///
///
///
public StandardGame(String name, Int32 port)
{
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.MinimumPasswordSize = 8;
this.AutoSave = true;
//Setup our server.
this.Server = new Server(this, port);
//Setup default save paths.
this.SavePaths = new DataPaths();
this.SavePaths.SetRelativePath("Data", DataTypes.Root);
this.World = new World(this);
}
///
/// Runs a script compiler and scans for custom scripts that
/// inherit StandardGame and then returns them. This provides
/// support for custom Game rules via Script.
///
///
public StandardGame Initialize()
{
//Instance a new compiler
CompileEngine compiler = new CompileEngine();
Logger.WriteLine("Checking for custom Game scripts.");
compiler.AddAssemblyReference(Path.Combine(this.SavePaths.GetPath(DataTypes.Root), Assembly.GetExecutingAssembly().Location));
Boolean result = compiler.Compile(this.SavePaths.GetPath(DataTypes.Scripts));
if (result)
{
ScriptFactory factory = new ScriptFactory(compiler.CompiledAssembly);
StandardGame game = (StandardGame)factory.FindInheritedScripted("StandardGame", "Mud Game");
if (game == null)
{
Logger.WriteLine("No custom Game rules located. Defaulting to Standard setup.");
return null;
}
else
{
Logger.WriteLine("Located " + game.GetType().Name + " ruleset.");
return game;
}
}
else
Logger.WriteLine("Failed to perform startup compilation! " + compiler.Errors);
return null;
}
///
/// Starts the game by getting all of the game scripts, loading the world
/// loading all of the games commands and starting the server.
///
///
///
///
public virtual Boolean Start(Int32 maxPlayers, Int32 maxQueueSize)
{
Logger.WriteLine("Starting up " + this.Name);
//Instance Script Engine
Logger.WriteLine("Preparing script engine...");
CompileEngine compiler = new CompileEngine("cs");
//compiler.AddAssemblyReference(Assembly.GetExecutingAssembly().FullName);
compiler.AddAssemblyReference(Path.Combine(this.SavePaths.GetPath(DataTypes.Root), Assembly.GetExecutingAssembly().Location));
//Compile any scripts
Logger.WriteLine("Compiling game scripts.");
Boolean result = compiler.Compile(this.SavePaths.GetPath(DataTypes.Scripts));
if (!result)
{
Logger.WriteLine(compiler.Errors, Logger.Importance.Error);
//Fail safe in the event compiling fails. Just use this assembly.
this.ScriptFactory = new ScriptFactory(Assembly.GetExecutingAssembly());
}
else
{
Logger.WriteLine("Compilation completed.");
this.ScriptFactory = new ScriptFactory(compiler.CompiledAssembly);
}
//Load the default engine Commands
Logger.WriteLine("Loading internal game commands.");
CommandSystem.LoadCommands();
if (CommandSystem.Commands.Count > 0)
{
foreach (ICommand command in CommandSystem.Commands.Values)
Logger.WriteLine("Loaded Command: " + command.Name);
}
else
Logger.WriteLine("No internal game commands located.");
Logger.WriteLine("Loading scripted game commands.");
ICommand[] commands = CommandSystem.LoadCommandLibrary(this.ScriptFactory.Assembly, false);
if (commands.Length > 0)
{
foreach (ICommand command in commands)
{
Logger.WriteLine("Loaded Command: " + command.Name);
}
}
else
Logger.WriteLine("No scripted game commands located.");
//Load World
this.World.Initialize();
this.World.Load();
//Start our server.
this.Server.Start(maxPlayers, maxQueueSize);
//If the server started without error, flag the Game as enabled.
if (this.Server.Enabled)
this.Enabled = true;
return this.Enabled;
}
///
/// Stops the game but unloading the world, shutting down the server and unloading all scripts/commands.
///
public void Stop()
{
//Save the world.
//Stop the server
this.Server.Stop();
//Stop the world.
//Purge all scripts and commands.
CommandSystem.PurgeCommands();
//Disable the game.
this.Enabled = false;
}
public void Update()
{
}
private void SetupPaths()
{
if (!Directory.Exists(this.SavePaths.GetPath(DataTypes.Characters)))
Directory.CreateDirectory(this.SavePaths.GetPath(DataTypes.Characters));
if (!Directory.Exists(this.SavePaths.GetPath(DataTypes.Environments)))
Directory.CreateDirectory(this.SavePaths.GetPath(DataTypes.Environments));
if (!Directory.Exists(this.SavePaths.GetPath(DataTypes.Equipment)))
Directory.CreateDirectory(this.SavePaths.GetPath(DataTypes.Equipment));
if (!Directory.Exists(this.SavePaths.GetPath(DataTypes.Players)))
Directory.CreateDirectory(this.SavePaths.GetPath(DataTypes.Players));
if (!Directory.Exists(this.SavePaths.GetPath(DataTypes.Scripts)))
Directory.CreateDirectory(this.SavePaths.GetPath(DataTypes.Scripts));
}
}
}