MudEngine:

- Corrected CommandLogin to support the Player.Send/Receive methods.
 - Re-organized the Game class source code and added additional commenting.
 - Began adding code to remove un-wanted characters in the received byte stream in Player.Receive()
This commit is contained in:
Scionwest_cp 2010-08-01 17:34:59 -07:00
parent 942b038b1b
commit 29cdae3b1a
5 changed files with 199 additions and 129 deletions

View file

@ -17,14 +17,40 @@ namespace MudEngine.Commands
public CommandResults Execute(string command, BaseCharacter player) public CommandResults Execute(string command, BaseCharacter player)
{ {
player.ActiveGame.SendMessage(player.ActiveGame.GameTitle, player); player.Send(player.ActiveGame.GameTitle);
player.ActiveGame.SendMessage(player.ActiveGame.Version, player); player.Send(player.ActiveGame.Version);
player.ActiveGame.SendMessage(player.ActiveGame.Story, player); player.Send(player.ActiveGame.Story);
player.ActiveGame.SendMessage("", player); player.Send("");
player.ActiveGame.SendMessage("Enter Character Name: ", player, false);
bool isLegal = false;
while (!isLegal)
{
player.Send("Enter Character Name: ", false);
string input = player.ReadInput();
bool foundName = false;
foreach (BaseCharacter bc in player.ActiveGame.PlayerCollection)
{
if (bc.Name == input)
{
player.Send("Character name already taken.");
foundName = true;
break;
}
}
if (!foundName)
{
isLegal = true;
player.Name = input;
}
}
player.Send("Welcome " + player.Name + "!");
//string playerName = player.Receive();
//TODO: Read user input... //TODO: Read user input...
return new CommandResults(); return new CommandResults();
} }
} }

View file

@ -16,6 +16,7 @@ using MudEngine.FileSystem;
using MudEngine.GameObjects; using MudEngine.GameObjects;
using MudEngine.GameObjects.Characters; using MudEngine.GameObjects.Characters;
using MudEngine.GameObjects.Environment; using MudEngine.GameObjects.Environment;
using MudEngine.Scripting;
namespace MudEngine.GameManagement namespace MudEngine.GameManagement
{ {
@ -26,6 +27,8 @@ namespace MudEngine.GameManagement
[XmlInclude(typeof(Currency))] [XmlInclude(typeof(Currency))]
public class Game public class Game
{ {
#region ==== Properties & Types ====
#region Custom Types
public enum TimeOfDayOptions public enum TimeOfDayOptions
{ {
AlwaysDay, AlwaysDay,
@ -33,6 +36,29 @@ namespace MudEngine.GameManagement
Transition, Transition,
} }
/// <summary>
/// Gets or Sets what time of day the world is currently in.
/// </summary>
[Category("Day Management")]
[Description("Set what time of day the world will take place in.")]
public TimeOfDayOptions TimeOfDay
{
get;
set;
}
#endregion
#region Game Object Setup
/// <summary>
/// Gets or Sets if this game is running in debug mode. Additional information is sent to the log if enabled.
/// </summary>
public static bool IsDebug { get; set; }
/// <summary>
/// Gets or Sets if the game will run with a server or not.
/// </summary>
public bool IsMultiplayer { get; set; }
/// <summary> /// <summary>
/// Gets or Sets if this game is currently running. /// Gets or Sets if this game is currently running.
/// </summary> /// </summary>
@ -40,12 +66,30 @@ namespace MudEngine.GameManagement
public bool IsRunning { get; internal set; } public bool IsRunning { get; internal set; }
/// <summary> /// <summary>
/// Gets or Sets if this game is running in debug mode. Additional information is sent to the log if enabled. /// Gets or Sets if all objects will be laoded during server startup. Enabling this results in a slower server start time, but faster object access.
/// </summary> /// </summary>
public static bool IsDebug { get; set; } [Category("Project Settings")]
[Description("If enabled, all objects will be loaded during server startup resulting in a slower server start time, but faster load time during gameplay")]
public bool PreCacheObjects { get; set; }
public bool IsMultiplayer { get; set; } /// <summary>
/// Gets or Sets the path to the current project
/// </summary>
[Browsable(false)]
public string ProjectPath { get; set; }
/// <summary>
/// Gets or Sets the paths to various project related objects.
/// </summary>
public SaveDataPaths DataPaths { get; set; }
/// <summary>
/// Gets the scripting engine used by the game.
/// </summary>
public ScriptEngine scriptEngine { get; internal set; }
#endregion
#region Game Information
[Category("Company Settings")] [Category("Company Settings")]
[Description("The name of the Company or Author building the game.")] [Description("The name of the Company or Author building the game.")]
/// <summary> /// <summary>
@ -64,6 +108,13 @@ namespace MudEngine.GameManagement
[Description("The name of the game displayed to the users, and title bar of the runtime.")] [Description("The name of the game displayed to the users, and title bar of the runtime.")]
public string GameTitle { get; set; } public string GameTitle { get; set; }
/// <summary>
/// Gets or Sets the current working version of the game.
/// </summary>
[Category("Project Settings")]
[Description("The current working version of the game.")]
public string Version { get; set; }
[Category("Project Settings")] [Category("Project Settings")]
[Description("Enable or Disable Auto-saving of players when the player travels")] [Description("Enable or Disable Auto-saving of players when the player travels")]
/// <summary> /// <summary>
@ -78,45 +129,19 @@ namespace MudEngine.GameManagement
/// </summary> /// </summary>
public bool HideRoomNames { get; set; } public bool HideRoomNames { get; set; }
/// <summary>
/// Gets or Sets what time of day the world is currently in.
/// </summary>
[Category("Day Management")]
[Description("Set what time of day the world will take place in.")]
public TimeOfDayOptions TimeOfDay
{
get;
set;
}
/// <summary> /// <summary>
/// Gets or Sets how long in minutes it takes to transition from day to night. /// Gets or Sets how long in minutes it takes to transition from day to night.
/// </summary> /// </summary>
[Category("Day Management")] [Category("Day Management")]
[Description("Set how long in minutes it takes to transition from day to night.")] [Description("Set how long in minutes it takes to transition from day to night.")]
public int TimeOfDayTransition public int TimeOfDayTransition { get; set; }
{
get;
set;
}
/// <summary> /// <summary>
/// Gets or Sets how long in minutes a day lasts in the game world. /// Gets or Sets how long in minutes a day lasts in the game world.
/// </summary> /// </summary>
[Category("Day Management")] [Category("Day Management")]
[Description("Sets how long in minutes a day lasts in the game world.")] [Description("Sets how long in minutes a day lasts in the game world.")]
public int DayLength public int DayLength { get; set; }
{
get;
set;
}
/// <summary>
/// Gets or Sets the current working version of the game.
/// </summary>
[Category("Project Settings")]
[Description("The current working version of the game.")]
public string Version { get; set; }
[Category("Game Currency")] [Category("Game Currency")]
[DefaultValue(1)] [DefaultValue(1)]
@ -127,30 +152,10 @@ namespace MudEngine.GameManagement
[Category("Game Currency")] [Category("Game Currency")]
[DefaultValue("Copper")] [DefaultValue("Copper")]
public string BaseCurrencyName { get; set; } public string BaseCurrencyName { get; set; }
//TODO: Add Party support.
/// <summary>
/// Gets or Sets if all objects will be laoded during server startup. Enabling this results in a slower server start time, but faster object access.
/// </summary>
[Category("Project Settings")]
[Description("If enabled, all objects will be loaded during server startup resulting in a slower server start time, but faster load time during gameplay")]
public bool PreCacheObjects { get; set; }
[Browsable(false)] [Browsable(false)]
public List<Currency> CurrencyList { get; set; } public List<Currency> CurrencyList { get; set; }
/// <summary>
/// Gets or Sets the path to the current project
/// </summary>
[Browsable(false)]
public string ProjectPath { get; set; }
/// <summary>
/// Gets or Sets the paths to various project related objects.
/// </summary>
public SaveDataPaths DataPaths { get; set; }
[Category("Environment Settings")] [Category("Environment Settings")]
[ReadOnly(true)] [ReadOnly(true)]
public Realm InitialRealm public Realm InitialRealm
@ -163,46 +168,73 @@ namespace MudEngine.GameManagement
/// </summary> /// </summary>
public List<Realm> RealmCollection { get; private set; } public List<Realm> RealmCollection { get; private set; }
[Browsable(false)] /// <summary>
public string Story /// The Story that is displayed on initial player entry into the game
{ /// </summary>
get; public string Story { get; set; }
set; #endregion
}
[Category("Object Setup")] #region Networking
public string Filename //TODO: This should be internal only; C# property using get; internal set; so only MudEngine.dll may edit this collection
{ /// <summary>
get /// Collection of players currently running on the server.
{ /// </summary>
return _Filename; internal BaseCharacter[] PlayerCollection;
}
}
private string _Filename;
/// <summary>
/// Gets the current running Server object.
/// </summary>
public MudEngine.Networking.Server Server { get; internal set; }
/// <summary>
/// Gets or Sets the protocol used by the server.
/// </summary>
public ProtocolType ServerType { get; set; }
/// <summary>
/// Gets or Sets the port that the server will run on
/// </summary>
public int ServerPort { get; set; }
/// <summary>
/// Gets or Sets the maximum number of Players permitted to run on this Games server.
/// </summary>
public int MaximumPlayers { get; set; }
#endregion
#endregion
#region ==== Constructors ====
public Game() public Game()
{ {
//Instance all of the Games Objects.
CurrencyList = new List<Currency>(); CurrencyList = new List<Currency>();
scriptEngine = new Scripting.ScriptEngine(this); scriptEngine = new Scripting.ScriptEngine(this);
RealmCollection = new List<Realm>(); RealmCollection = new List<Realm>();
//Prepare the Save Paths for all of our Game objects.
SaveDataPaths paths = new SaveDataPaths(); SaveDataPaths paths = new SaveDataPaths();
paths.Environment = FileManager.GetDataPath(SaveDataTypes.Realms); paths.Environment = FileManager.GetDataPath(SaveDataTypes.Realms);
paths.Players = FileManager.GetDataPath(SaveDataTypes.Player); paths.Players = FileManager.GetDataPath(SaveDataTypes.Player);
DataPaths = paths; DataPaths = paths;
//Setup default settings for the Game
GameTitle = "New Game"; GameTitle = "New Game";
_Filename = "Game.xml";
BaseCurrencyAmount = 1; BaseCurrencyAmount = 1;
BaseCurrencyName = "Copper"; BaseCurrencyName = "Copper";
IsMultiplayer = true; //default.
Version = "1.0"; Version = "1.0";
Story = ""; Story = "";
}
//Setup default Networking settings
IsMultiplayer = true;
ServerType = ProtocolType.Tcp;
ServerPort = 555;
MaximumPlayers = 1000;
}
#endregion
#region ==== Methods ====
/// <summary> /// <summary>
/// Starts the game. /// Starts the game and runs the server if IsMultiplayer is true
/// </summary> /// </summary>
public bool Start() public bool Start()
{ {
@ -213,8 +245,6 @@ namespace MudEngine.GameManagement
Log.Write("Loading internal game commands..."); Log.Write("Loading internal game commands...");
//Loads the MudEngine Game Commands //Loads the MudEngine Game Commands
CommandEngine.LoadBaseCommands(); CommandEngine.LoadBaseCommands();
//Loads any commands found in the users custom scripts library loaded by the script engine.
//CommandEngine.LoadCommandLibrary(scriptEngine.Assembly);
//Ensure custom commands are loaded until everything is fleshed out. //Ensure custom commands are loaded until everything is fleshed out.
if (Game.IsDebug) if (Game.IsDebug)
@ -236,6 +266,7 @@ namespace MudEngine.GameManagement
} }
} }
//Check if any the initial room exists or not.
if ((InitialRealm == null) || (InitialRealm.InitialZone == null) || (InitialRealm.InitialZone.InitialRoom == null)) if ((InitialRealm == null) || (InitialRealm.InitialZone == null) || (InitialRealm.InitialZone.InitialRoom == null))
{ {
Log.Write("ERROR: No initial location defined. Game startup failed!"); Log.Write("ERROR: No initial location defined. Game startup failed!");
@ -249,17 +280,23 @@ namespace MudEngine.GameManagement
if (IsMultiplayer) if (IsMultiplayer)
this.StartServer(); this.StartServer();
//Game is running now.
IsRunning = true; IsRunning = true;
Log.Write("Game startup complete."); Log.Write("Game startup complete.");
return true; return true;
} }
/// <summary>
/// Shuts down the Game and Server.
/// </summary>
public void Shutdown() public void Shutdown()
{ {
Log.Write("Server shutdown requested..."); Log.Write("Server shutdown requested...");
//Place ending code here for game shut down. //Place ending code here for game shut down.
//TODO: Save content on shutdown. //TODO: Save content on shutdown.
if (IsMultiplayer) if (IsMultiplayer)
Server.EndServer(); Server.EndServer();
@ -268,29 +305,14 @@ namespace MudEngine.GameManagement
Log.Write("Shutdown completed..."); Log.Write("Shutdown completed...");
} }
public void Save(string filename) /// <summary>
{ /// Adds a Realm to the Games current list of Realms.
string directory = Path.GetDirectoryName(filename); /// </summary>
/// <param name="realm"></param>
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
//FileManager.Save(filename, this);
}
public bool Load(string path)
{
string fileName = Path.Combine(path, _Filename);
if (!File.Exists(fileName))
{
return false;
}
return true;
}
public void AddRealm(Realm realm) public void AddRealm(Realm realm)
{ {
//If this Realm is set as Initial then we need to disable any previously
//set Realms to avoid conflict.
if (realm.IsInitialRealm) if (realm.IsInitialRealm)
{ {
foreach (Realm r in RealmCollection) foreach (Realm r in RealmCollection)
@ -303,6 +325,7 @@ namespace MudEngine.GameManagement
} }
} }
//Set this Realm as the Games initial Realm
if (realm.IsInitialRealm) if (realm.IsInitialRealm)
InitialRealm = realm; InitialRealm = realm;
@ -310,6 +333,11 @@ namespace MudEngine.GameManagement
RealmCollection.Add(realm); RealmCollection.Add(realm);
} }
/// <summary>
/// Gets a Realm currently stored in the Games collection of Realms.
/// </summary>
/// <param name="realmName"></param>
/// <returns></returns>
public Realm GetRealm(string realmName) public Realm GetRealm(string realmName)
{ {
foreach (Realm realm in RealmCollection) foreach (Realm realm in RealmCollection)
@ -321,17 +349,9 @@ namespace MudEngine.GameManagement
return null; return null;
} }
//TODO: This should be internal only; C# property using get; internal set; so only MudEngine.dll may edit this collection /// <summary>
//public List<BaseCharacter> PlayerCollection; /// Starts the Server.
public BaseCharacter[] PlayerCollection; /// </summary>
public MudEngine.Networking.Server Server { get; internal set; }
public ProtocolType ServerType = ProtocolType.Tcp;
public int ServerPort = 555;
public int MaximumPlayers = 1000;
private Scripting.ScriptEngine scriptEngine;
private void StartServer() private void StartServer()
{ {
//This is handled by the Game() Constructor //This is handled by the Game() Constructor
@ -343,19 +363,6 @@ namespace MudEngine.GameManagement
Server.Initialize(ServerPort, ref PlayerCollection); Server.Initialize(ServerPort, ref PlayerCollection);
Server.Start(); Server.Start();
} }
#endregion
public void SendMessage(string message, BaseCharacter player)
{
SendMessage(message, player, true);
}
public void SendMessage(string message, BaseCharacter player, bool newLine)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
if (newLine)
message += "\n\r";
player.Send(encoding.GetBytes(message));
}
} }
} }

View file

@ -154,11 +154,19 @@ namespace MudEngine.GameObjects.Characters
Disconnect(); Disconnect();
} }
internal void Send(string data) /// <summary>
/// Sends data to the player.
/// </summary>
/// <param name="data"></param>
/// <param name="newLine"></param>
internal void Send(string data, bool newLine)
{ {
try try
{ {
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
if (newLine)
data += "\n\r";
client.Send(encoding.GetBytes(data)); client.Send(encoding.GetBytes(data));
} }
catch (Exception) // error, connection failed: close client catch (Exception) // error, connection failed: close client
@ -166,11 +174,22 @@ namespace MudEngine.GameObjects.Characters
Disconnect(); Disconnect();
} }
} }
/// <summary>
/// Sends data to the player.
/// </summary>
/// <param name="data"></param>
internal void Send(string data)
{
Send(data, true);
}
internal void Disconnect() internal void Disconnect()
{ {
string filePath = Path.Combine(ActiveGame.DataPaths.Players, Filename); string filePath = Path.Combine(ActiveGame.DataPaths.Players, Filename);
this.Save(filePath); this.Save(filePath);
Send("Disconnecting...");
IsActive = false; IsActive = false;
client.Close(); client.Close();
// TODO: Reset game so it can be used again // TODO: Reset game so it can be used again
@ -193,8 +212,18 @@ namespace MudEngine.GameObjects.Characters
buffer.RemoveAt(buffer.Count-1); buffer.RemoveAt(buffer.Count-1);
String str; String str;
List<byte> correctedBuffer = new List<byte>();
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
str = enc.GetString(buffer.ToArray()); foreach (byte i in buffer)
{
if (i == 255)
continue;
else if (i == 251)
continue;
else
correctedBuffer.Add(i);
}
str = enc.GetString(correctedBuffer.ToArray());
return str; return str;
} }
else else

View file

@ -112,8 +112,12 @@ namespace MudEngine.Networking
if (sub > 0 && sub < players./*Capacity*/Length) if (sub > 0 && sub < players./*Capacity*/Length)
{ {
clientThreads[sub].Abort(); clientThreads[sub].Abort();
if(players[sub].IsActive) if (players[sub].IsActive)
{
Log.Write("Disconnecting player " + players[sub].Name);
players[sub].Disconnect(); players[sub].Disconnect();
Log.Write("Player disconnected.");
}
} }
} }

View file

@ -2,7 +2,9 @@
using System; using System;
using System.CodeDom; using System.CodeDom;
using System.CodeDom.Compiler; using System.CodeDom.Compiler;
#if !MOBILE
using Microsoft.CSharp; using Microsoft.CSharp;
#endif
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
@ -101,6 +103,7 @@ namespace MudEngine.Scripting
/// <returns></returns> /// <returns></returns>
public bool CompileScripts() public bool CompileScripts()
{ {
#if !MOBILE
//Ensure the script path exists. //Ensure the script path exists.
if (!System.IO.Directory.Exists(ScriptPath)) if (!System.IO.Directory.Exists(ScriptPath))
{ {
@ -180,6 +183,7 @@ namespace MudEngine.Scripting
} }
else else
return true; return true;
#endif
} }
/// <summary> /// <summary>