MudEngine:

- Login command now supports Offline games. Skips various things that are server related only.
 - Added a constructor to SaveDataPaths for quickly being able to assign paths.
 - Game.Start is now Virtual so that scripts may override it.
 - Game.Start now supports single player games and initializes players within it.
 - Log now provides a Verbose mode so that Singleplayer games no longer gets flooded with Game startup messages.
 - BaseCharacter.Initialize() Initialize no longer crashes when called with IsMultiplayer set to false.
 - BaseCharacter.ReadInput() now supports IsMultiplayer being false.

MudServer:
 - Now supports singleplayer and multiplayer games within a single application. 
 - MudServer is now ready to be re-named to MudGame and will be used for both Offline and Online games.
This commit is contained in:
Scionwest_cp 2010-08-08 18:05:21 -07:00
parent ef7cc5d2c2
commit aade5f797f
7 changed files with 188 additions and 55 deletions

View file

@ -43,11 +43,14 @@ namespace MudEngine.Commands
} }
//Next search if there is an existing player already logged in with this name, if so disconnect them. //Next search if there is an existing player already logged in with this name, if so disconnect them.
foreach (BaseCharacter character in player.ActiveGame.PlayerCollection) if (player.ActiveGame.IsMultiplayer)
{ {
if (character.Name.ToLower() == input.ToLower()) for (int i = 0; i <= player.ActiveGame.PlayerCollection.Length - 1; i++)
{ {
character.Disconnect(); if (player.ActiveGame.PlayerCollection[i].Name.ToLower() == input.ToLower())
{
player.ActiveGame.PlayerCollection[i].Disconnect();
}
} }
} }
@ -65,22 +68,24 @@ namespace MudEngine.Commands
//Look to see if there are players in the Room //Look to see if there are players in the Room
//Let other players know that the user walked in. //Let other players know that the user walked in.
for (int i = 0; i != player.ActiveGame.PlayerCollection.Length; i++) if (player.ActiveGame.IsMultiplayer)
{ {
if (player.ActiveGame.PlayerCollection[i].Name == player.Name) for (int i = 0; i != player.ActiveGame.PlayerCollection.Length; i++)
continue;
string room = player.ActiveGame.PlayerCollection[i].CurrentRoom.Name;
string realm = player.ActiveGame.PlayerCollection[i].CurrentRoom.Realm;
string zone = player.ActiveGame.PlayerCollection[i].CurrentRoom.Zone;
if ((room == player.CurrentRoom.Name) && (realm == player.CurrentRoom.Realm) && (zone == player.CurrentRoom.Zone))
{ {
player.ActiveGame.PlayerCollection[i].Send(player.Name + " arrived."); if (player.ActiveGame.PlayerCollection[i].Name == player.Name)
continue;
string room = player.ActiveGame.PlayerCollection[i].CurrentRoom.Name;
string realm = player.ActiveGame.PlayerCollection[i].CurrentRoom.Realm;
string zone = player.ActiveGame.PlayerCollection[i].CurrentRoom.Zone;
if ((room == player.CurrentRoom.Name) && (realm == player.CurrentRoom.Realm) && (zone == player.CurrentRoom.Zone))
{
player.ActiveGame.PlayerCollection[i].Send(player.Name + " arrived.");
}
} }
} }
//player.CommandSystem.ExecuteCommand("Look", player); //Handled in BaseCharacter.Initialize() now.
return new CommandResults(); return new CommandResults();
} }
} }

View file

@ -32,7 +32,7 @@ namespace MudEngine.Commands
} }
} }
else else
player.Save(filename); //Should never be called? player.Save(filename); //Should never be called?
return new CommandResults(); return new CommandResults();
} }

View file

@ -7,7 +7,36 @@ namespace MudEngine.FileSystem
{ {
public struct SaveDataPaths public struct SaveDataPaths
{ {
public string Players { get; set; } public string Players
public string Environment { get; set; } {
get
{
return _Players;
}
set
{
_Players = value;
}
}
public string Environment
{
get
{
return _Environment;
}
set
{
_Environment = value;
}
}
private string _Players;
private string _Environment;
public SaveDataPaths(string environment, string players)
{
_Players = players;
_Environment = environment;
}
} }
} }

View file

@ -241,7 +241,7 @@ namespace MudEngine.GameManagement
/// <summary> /// <summary>
/// Starts the game and runs the server if IsMultiplayer is true /// Starts the game and runs the server if IsMultiplayer is true
/// </summary> /// </summary>
public bool Start() public virtual bool Start()
{ {
Log.Write("Game Initializing..."); Log.Write("Game Initializing...");
if (!Directory.Exists(DataPaths.Players)) if (!Directory.Exists(DataPaths.Players))
@ -300,6 +300,12 @@ namespace MudEngine.GameManagement
Log.Write("Starting Server..."); Log.Write("Starting Server...");
this.StartServer(); this.StartServer();
} }
else //Not multiplayer so we change the save locations
{
SaveDataPaths paths = new SaveDataPaths("World", "Saved");
DataPaths = paths;
PlayerCollection[0].Initialize();
}
//Game is running now. //Game is running now.
IsRunning = true; IsRunning = true;
@ -315,17 +321,35 @@ namespace MudEngine.GameManagement
{ {
Log.Write("Server shutdown requested..."); Log.Write("Server shutdown requested...");
//Place ending code here for game shut down.
//TODO: Save content on shutdown.
if (IsMultiplayer) if (IsMultiplayer)
Server.EndServer(); Server.EndServer();
Save();
IsRunning = false; IsRunning = false;
Log.Write("Shutdown completed..."); Log.Write("Shutdown completed...");
} }
public void Save()
{
Log.Write("Saving Game world....");
Log.Write("Saving Game Players...");
for (int i = 0; i <= PlayerCollection.Length - 1; i++)
{
if (PlayerCollection[i].Name == "New BaseCharacter")
continue;
Log.Write("Saving " + PlayerCollection[i].Name);
PlayerCollection[i].Save(Path.Combine(DataPaths.Players, PlayerCollection[i].Filename));
}
}
public void Load()
{
}
/// <summary> /// <summary>
/// Adds a Realm to the Games current list of Realms. /// Adds a Realm to the Games current list of Realms.
/// </summary> /// </summary>

View file

@ -11,6 +11,7 @@ namespace MudEngine.GameManagement
public static class Log public static class Log
{ {
static List<string> cachedMessages = new List<string>(); static List<string> cachedMessages = new List<string>();
public static Boolean IsVerbose;
public static void Write(string message) public static void Write(string message)
{ {
@ -39,7 +40,7 @@ namespace MudEngine.GameManagement
sb.AppendLine(message); sb.AppendLine(message);
} }
if (sb.ToString() == "") if ((sb.ToString() == "") || (IsVerbose))
return ""; return "";
else else
return sb.ToString(); return sb.ToString();

View file

@ -195,7 +195,7 @@ namespace MudEngine.GameObjects.Characters
Send(""); //Blank line to help readability. Send(""); //Blank line to help readability.
//Now that the command has been executed, restore the Command: message //Now that the command has been executed, restore the Command: message
//Send("Command: ", false); Send("Command: ", false);
/* No longer needed due to player.send() sending content to the player. /* No longer needed due to player.send() sending content to the player.
if (result.Result != null) if (result.Result != null)
@ -213,7 +213,8 @@ namespace MudEngine.GameObjects.Characters
internal void Initialize() internal void Initialize()
{ {
client.Receive(new byte[255]); if (ActiveGame.IsMultiplayer)
client.Receive(new byte[255]);
if (Game.IsDebug) if (Game.IsDebug)
Log.Write("New Player Connected."); Log.Write("New Player Connected.");
@ -302,35 +303,42 @@ namespace MudEngine.GameObjects.Characters
} }
internal string ReadInput() internal string ReadInput()
{ {
List<byte> buffer = new List<byte>(); if (ActiveGame.IsMultiplayer)
while (true)
{ {
try List<byte> buffer = new List<byte>();
while (true)
{ {
byte[] buf = new byte[1]; try
int recved = client.Receive(buf);
if (recved > 0)
{ {
if (buf[0] == '\n' && buffer.Count > 0) byte[] buf = new byte[1];
{ int recved = client.Receive(buf);
if (buffer[buffer.Count-1] == '\r')
buffer.RemoveAt(buffer.Count-1);
String str; if (recved > 0)
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); {
str = enc.GetString(buffer.ToArray()); if (buf[0] == '\n' && buffer.Count > 0)
return str; {
if (buffer[buffer.Count - 1] == '\r')
buffer.RemoveAt(buffer.Count - 1);
String str;
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
str = enc.GetString(buffer.ToArray());
return str;
}
else
buffer.Add(buf[0]);
} }
else }
buffer.Add(buf[0]); catch (Exception e)
{
Disconnect();
return e.Message;
} }
} }
catch (Exception e) }
{ else
Disconnect(); {
return e.Message; return Console.ReadLine();
}
} }
} }

View file

@ -15,25 +15,35 @@ namespace MudServer
{ {
static class Program static class Program
{ {
const string SettingsFile = "Settings.ini";
static void Main(string[] args) static void Main(string[] args)
{ {
if (FileManager.GetData(SettingsFile, "ServerEnabled").ToLower() == "false")
Log.IsVerbose = true;
else if (FileManager.GetData(SettingsFile, "ServerEnabled").ToLower() == "")
Log.IsVerbose = false;
else
Log.IsVerbose = false;
Log.Write("Launching..."); Log.Write("Launching...");
ScriptEngine scriptEngine; ScriptEngine scriptEngine;
Game game; Game game;
//Re-create the settings file if it is missing //Re-create the settings file if it is missing
if (!File.Exists("Settings.ini")) if (!File.Exists(SettingsFile))
{ {
Log.Write("Settings.ini missing!"); Log.Write("Settings.ini missing!");
FileManager.WriteLine("Settings.ini", "Scripts", "ScriptPath"); FileManager.WriteLine(SettingsFile, "Scripts", "ScriptPath");
FileManager.WriteLine("Settings.ini", ".cs", "ScriptExtension"); FileManager.WriteLine(SettingsFile, ".cs", "ScriptExtension");
FileManager.WriteLine(SettingsFile, "True", "ServerEnabled");
Log.Write("Settings.ini re-created with default values"); Log.Write("Settings.ini re-created with default values");
} }
Log.Write("Loading settings..."); Log.Write("Loading settings...");
scriptEngine = new ScriptEngine(new Game(), ScriptEngine.ScriptTypes.SourceFiles); scriptEngine = new ScriptEngine(new Game(), ScriptEngine.ScriptTypes.SourceFiles);
scriptEngine.ScriptPath = FileManager.GetData("Settings.ini", "ScriptPath"); scriptEngine.ScriptPath = FileManager.GetData(SettingsFile, "ScriptPath");
scriptEngine.ScriptExtension = FileManager.GetData("Settings.ini", "ScriptExtension"); scriptEngine.ScriptExtension = FileManager.GetData(SettingsFile, "ScriptExtension");
//scriptEngine.CompileScripts(); //scriptEngine.CompileScripts();
Log.Write("Initializing Script Engine for Script Compilation..."); Log.Write("Initializing Script Engine for Script Compilation...");
@ -68,13 +78,69 @@ namespace MudServer
Console.WriteLine(Log.GetMessages()); Console.WriteLine(Log.GetMessages());
Log.FlushMessages(); Log.FlushMessages();
//Server is only enabled if the option is in the settings file
//Allows developers to remove the option from the settings file and letting
//people host multiplayer games with the singleplayer MUD.
//People won't know that it's an option if the option doesn't exist so if no
//option is found in the sttings file, then we assume offline play.
if (FileManager.GetData(SettingsFile, "ServerEnabled").ToLower() == "false")
game.IsMultiplayer = false;
else if (FileManager.GetData(SettingsFile, "ServerEnabled").ToLower() == "")
game.IsMultiplayer = false;
else
game.IsMultiplayer = true;
game.Start(); game.Start();
//Make sure the Game is in fact running.
if (!game.IsRunning)
{
Console.WriteLine("Error starting game!\nReview Log file for details.");
return;
}
//If the game isn't in multiplayer mode, then the server doesn't create an instance of the players
//We need to make sure that the Game created one. The default game handles this, but inherited Game
//scripts might miss this, so we check for it.
if (!game.IsMultiplayer)
{
if ((game.PlayerCollection[0] == null) || (game.PlayerCollection[0].Name == "New BaseCharacter"))
{
Console.WriteLine("Error! No player available for creation!");
return;
}
}
DateTime serverTime = new DateTime();
DateTime systemTime = DateTime.Now;
int lastSaveGap = 0;
while (game.IsRunning) while (game.IsRunning)
{ {
Console.Write(Log.GetMessages()); if (lastSaveGap == 30)
Log.FlushMessages(); {
System.Threading.Thread.Sleep(1); game.Save();
lastSaveGap = 0;
}
if (serverTime.Minute != DateTime.Now.Minute)
{
serverTime = DateTime.Now;
lastSaveGap++;
}
if (game.IsMultiplayer)
{
Console.Write(Log.GetMessages());
Log.FlushMessages();
System.Threading.Thread.Sleep(1);
}
else
{
game.PlayerCollection[0].ExecuteCommand(Console.ReadLine());
}
} }
} }
} }