* XMLData.Save now has exception handling code in-place.

* Added better commenting to the majority of the projects files.
* Removed command support from the server console.
* Added a Client side command STOP that can be used to shut down the server.  In the future that will be specific to Admins only.
* Characters now have their save code invoked during server shut down.
* Server shut down code added.  Server.Stop() fully implemented.
This commit is contained in:
Scionwest_cp 2012-03-03 13:24:35 -08:00
parent b5c9f2967a
commit f0ec29c240
8 changed files with 148 additions and 14 deletions

View file

@ -28,8 +28,15 @@ namespace MudEngine.DAL
public Boolean Save(String filename) public Boolean Save(String filename)
{ {
this.SaveData.Save(filename); try
return true; {
this.SaveData.Save(filename);
return true;
}
catch
{
return false;
}
} }
} }
} }

View file

@ -101,9 +101,13 @@ namespace MudEngine.Game.Characters
this.Enabled = true; this.Enabled = true;
} }
/// <summary>
/// Destroys any resources used by this character.
/// Assumes that Save() has already been invoked.
/// </summary>
public void Destroy() public void Destroy()
{ {
throw new NotImplementedException(); this.Commands = null;
} }
internal void ExecuteCommand(string command) internal void ExecuteCommand(string command)
@ -183,6 +187,9 @@ namespace MudEngine.Game.Characters
{ {
Console.WriteLine("Disconnecting..."); Console.WriteLine("Disconnecting...");
//Purge all of this characters commands.
this.Destroy();
//Close our currently open socket. //Close our currently open socket.
this._Connection.Close(); this._Connection.Close();
//this._LoopThread.Abort(); //this._LoopThread.Abort();

View file

@ -6,37 +6,86 @@ using System.Text;
using MudEngine.Networking; using MudEngine.Networking;
using MudEngine.Core; using MudEngine.Core;
using MudEngine.Game.Characters;
namespace MudEngine.Game namespace MudEngine.Game
{ {
/// <summary>
/// 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.
/// </summary>
public class StandardGame public class StandardGame
{ {
/// <summary>
/// Gets or Sets the Name of this game.
/// </summary>
public String Name { get; set; } public String Name { get; set; }
/// <summary>
/// Gets or Sets the website where this game can be played at.
/// </summary>
public String Website { get; set; } public String Website { get; set; }
/// <summary>
/// Gets or Sets the Description of this game. This is often displayed upon first connection.
/// Note that this is displayed BEFORE the Servers MOTD.
/// </summary>
public String Description { get; set; } public String Description { get; set; }
/// <summary>
/// Gets or Sets the Version of this game.
/// </summary>
public String Version { get; set; } public String Version { get; set; }
/// <summary>
/// Gets or Sets if Room Names will be shown to the player each time they travel to a new Room.
/// </summary>
public Boolean HiddenRoomNames { get; set; } public Boolean HiddenRoomNames { get; set; }
/// <summary>
/// Gets or Sets if this Game is currently being played on a Server
/// </summary>
public Boolean Multiplayer { get; set; } public Boolean Multiplayer { get; set; }
/// <summary>
/// Gets or Sets the minimum password size required for user account passwords
/// </summary>
public Int32 MinimumPasswordSize { get; set; } public Int32 MinimumPasswordSize { get; set; }
/// <summary>
/// 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.
/// </summary>
public Boolean AutoSave { get; set; } public Boolean AutoSave { get; set; }
/// <summary>
/// Gets if the game is currently running or not.
/// </summary>
public Boolean Enabled { get; private set; } public Boolean Enabled { get; private set; }
/// <summary>
/// Gets or Sets if the game is in debug more or not.
/// </summary>
public Boolean Debugging { get; set; } public Boolean Debugging { get; set; }
/// <summary>
/// Gets or reference to the currently running Server.
/// </summary>
public Server Server { get; protected set; } public Server Server { get; protected set; }
/// <summary>
/// StandardGame constructor. If no Port number is provided, 4000 is used.
/// </summary>
/// <param name="name"></param>
public StandardGame(String name) : this(name, 4000) public StandardGame(String name) : this(name, 4000)
{ {
} }
/// <summary>
/// StandardGame constructor.
/// </summary>
/// <param name="name"></param>
/// <param name="port"></param>
public StandardGame(String name, Int32 port) public StandardGame(String name, Int32 port)
{ {
Logger.WriteLine("Initializing Standard Mud Game"); Logger.WriteLine("Initializing Standard Mud Game");
@ -52,6 +101,13 @@ namespace MudEngine.Game
this.Server = new Server(this, port); this.Server = new Server(this, port);
} }
/// <summary>
/// Starts the game by getting all of the game scripts, loading the world
/// loading all of the games commands and starting the server.
/// </summary>
/// <param name="maxPlayers"></param>
/// <param name="maxQueueSize"></param>
/// <returns></returns>
public Boolean Start(Int32 maxPlayers, Int32 maxQueueSize) public Boolean Start(Int32 maxPlayers, Int32 maxQueueSize)
{ {
Logger.WriteLine("Starting up Standard Game"); Logger.WriteLine("Starting up Standard Game");
@ -75,13 +131,28 @@ namespace MudEngine.Game
return this.Enabled; return this.Enabled;
} }
/// <summary>
/// Stops the game but unloading the world, shutting down the server and unloading all scripts/commands.
/// </summary>
public void Stop() public void Stop()
{ {
//Save the world. //Save the world.
//Stop the server
this.Server.Stop(); this.Server.Stop();
//Stop the world.
//Purge all scripts and commands.
CommandSystem.PurgeCommands();
//Disable the game.
this.Enabled = false; this.Enabled = false;
} }
public void Update()
{
}
} }
} }

View file

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MudEngine.Core.Interface;
using MudEngine.Game;
using MudEngine.Game.Characters;
using MudEngine.Networking;
namespace MudEngine.GameScripts.Commands
{
public class CommandStop : ICommand
{
public string Name { get; set; }
public string Description { get; set; }
public List<string> Help { get; set; }
public CommandStop()
{
this.Name = "Stop";
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;
//Stop the game.
new Thread(game.Stop).Start();
}
}
}

View file

@ -75,6 +75,7 @@ namespace MudEngine.Networking
/// <param name="character"></param> /// <param name="character"></param>
public void RemoveConnection(StandardCharacter character) public void RemoveConnection(StandardCharacter character)
{ {
character.Save(character.Filename);
character.Disconnect(); character.Disconnect();
foreach (StandardCharacter c in this._ConnectedCharacters) foreach (StandardCharacter c in this._ConnectedCharacters)
{ {

View file

@ -79,6 +79,15 @@ namespace MudEngine.Networking
public void Stop() public void Stop()
{ {
this.ConnectionManager.DisconnectAll();
this._ServerThread.Abort();
this._Server.Close();
this._Server = null;
this.Enabled = false;
this.Status = ServerStatus.Stopped;
} }
private void ServerLoop() private void ServerLoop()

View file

@ -37,6 +37,7 @@
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@ -56,6 +57,7 @@
<Compile Include="DAL\XMLData.cs" /> <Compile Include="DAL\XMLData.cs" />
<Compile Include="GameScripts\Commands\CommandLogin.cs" /> <Compile Include="GameScripts\Commands\CommandLogin.cs" />
<Compile Include="GameScripts\Commands\CommandSay.cs" /> <Compile Include="GameScripts\Commands\CommandSay.cs" />
<Compile Include="GameScripts\Commands\CommandStop.cs" />
<Compile Include="Game\Characters\CharacterRoles.cs" /> <Compile Include="Game\Characters\CharacterRoles.cs" />
<Compile Include="Game\Characters\CharacterStats.cs" /> <Compile Include="Game\Characters\CharacterStats.cs" />
<Compile Include="Game\Characters\MyCharacter.cs" /> <Compile Include="Game\Characters\MyCharacter.cs" />

View file

@ -38,28 +38,28 @@ namespace WinPC_Server
game.Start(100, 20); game.Start(100, 20);
//Setup our Server console input class //Setup our Server console input class
/*
ConsoleInput input = new ConsoleInput(); ConsoleInput input = new ConsoleInput();
//Run the console input on its own thread. //Run the console input on its own thread.
Thread inputThread = new Thread(input.GetInput); Thread inputThread = new Thread(input.GetInput);
inputThread.Start(); inputThread.Start();
*/
//Game loops until it is disabled. //Game loops until it is disabled.
while (game.Enabled) while (game.Enabled)
{ {
//Check the queued Console Input game.Update();
if (input.Message.ToLower().Equals("exit"))
{
//If the server console has a exit command entered.
//stop the game. This will set game.Enabled to false.
game.Stop();
}
else
input.Message = String.Empty;
} }
//Kill the Console Input thread. //Kill the Console Input thread.
/*
inputThread.Abort(); inputThread.Abort();
inputThread = null;
input = null;
*/
game = null;
System.Windows.Forms.Application.Exit();
} }
} }
} }