MudEngine:

- Updated all game commands to support the new Player.Send() method. Returning CommandResults is no longer supported.
 - Login command now executes the Look command upon completing login.
 - Look command now supports Rooms DetailDescription property. Use this for multi-line descriptions.
 - Several changes to the Restart command. Still not working fully however, it no longer calls duplicate methods.
 - Fixed Walk command not moving players around.
 - Loading engine commands no longer happens more than once.
 - Added additional Server Console log output
 - BaseCharacter.Send() now correctly displays content to the user and prints the "Command:" message to the player after every command completed.
 - The Server now sets Player.IsControlled to true when a player connects.
 - BaseCharacter.Send() checks if the game is multi-player or not. If it is, it prints to Console, if not then prints to telnet clients.

Mud Offline Example:
 - Updated Zeroth Realm creation to use Room.DetailDescription now that the Look command supports it.
 - Updated the Game loop. No longer needs to print to the console due to the player.Execute() command automatically printing content to the console.

Mud Server:
 - Removed player from server as it was not being used any longer.
This commit is contained in:
Scionwest_cp 2010-08-03 20:20:24 -07:00
parent 5c8c5b6ba1
commit 0f45ecec53
12 changed files with 116 additions and 61 deletions

View file

@ -53,6 +53,7 @@ namespace MudEngine.Commands
} }
player.Send("Welcome " + player.Name + "!"); player.Send("Welcome " + player.Name + "!");
player.CommandSystem.ExecuteCommand("Look", player);
return new CommandResults(); return new CommandResults();
} }
} }

View file

@ -19,16 +19,22 @@ namespace MudEngine.Commands
public CommandResults Execute(string command, BaseCharacter player) public CommandResults Execute(string command, BaseCharacter player)
{ {
StringBuilder desc = new StringBuilder();
if (player.CurrentRoom == null) if (player.CurrentRoom == null)
{ {
return new CommandResults("Not within a created Room."); return new CommandResults("Not within a created Room.");
} }
desc.AppendLine(player.CurrentRoom.Description); if (player.CurrentRoom.DetailedDescription.Count == 0)
player.Send(player.CurrentRoom.Description);
else
{
foreach(string entry in player.CurrentRoom.DetailedDescription)
{
player.Send(entry);
}
}
return new CommandResults(desc.ToString()); return new CommandResults();
} }
} }
} }

View file

@ -32,8 +32,17 @@ namespace MudEngine.Commands
string filename = Path.Combine(path, player.ActiveGame.PlayerCollection[i].Filename); string filename = Path.Combine(path, player.ActiveGame.PlayerCollection[i].Filename);
player.ActiveGame.PlayerCollection[i].Save(filename); player.ActiveGame.PlayerCollection[i].Save(filename);
} }
player.ActiveGame.Server.EndServer();
//player.ActiveGame.Server.EndServer(); //-Handled in Game.Shutdown() below.
player.ActiveGame.Shutdown();
player.ActiveGame.Start();
/* Game.Start() calls this, do we need a reference to the playercollection?
* They should be unloaded anyway and re-loaded during game.start to force a clean restart of all objects.
player.ActiveGame.Server.Initialize(555, ref player.ActiveGame.PlayerCollection); player.ActiveGame.Server.Initialize(555, ref player.ActiveGame.PlayerCollection);
*/
Console.WriteLine("Server Restart Completed.");
//This is never printed as CommandResults is no longer outputted to the player console, player.Send is used
return new CommandResults("Server Restarted."); return new CommandResults("Server Restarted.");
} }
return new CommandResults("Access Denied."); return new CommandResults("Access Denied.");

View file

@ -33,13 +33,9 @@ namespace MudEngine.Commands
//Move the player into their new room //Move the player into their new room
player.Move(door.TravelDirection); player.Move(door.TravelDirection);
CommandResults cmd = player.CommandSystem.ExecuteCommand("Look", player); player.CommandSystem.ExecuteCommand("Look", player);
string lookValue = "";
if (cmd.Result.Length != 0) return null;
lookValue = cmd.Result[0].ToString();
return new CommandResults(new object[] { lookValue, player.CurrentRoom });
} }
} }
} }

View file

@ -19,23 +19,23 @@ namespace MudEngine.GameManagement
/// <summary> /// <summary>
/// Gets or Sets a Dictionary list of available commands to use. /// Gets or Sets a Dictionary list of available commands to use.
/// </summary> /// </summary>
public Dictionary<string, IGameCommand> CommandCollection { get; set; } public static Dictionary<string, IGameCommand> CommandCollection { get; set; }
internal Dictionary<string, IGameCommand> _Commands { get; set; } internal Dictionary<string, IGameCommand> __Commands { get; set; }
public CommandEngine() public CommandEngine()
{ {
if ((CommandCollection == null) || (CommandCollection.Count == 0)) if ((CommandEngine.CommandCollection == null) || (CommandEngine.CommandCollection.Count == 0))
LoadBaseCommands(); CommandEngine.LoadBaseCommands();
_Commands = CommandCollection; //_Commands = CommandEngine.CommandCollection;
} }
public List<string> GetCommands() public static List<string> GetCommands()
{ {
List<string> temp = new List<string>(); List<string> temp = new List<string>();
foreach (string name in CommandCollection.Keys) foreach (string name in CommandEngine.CommandCollection.Keys)
{ {
temp.Add(name); temp.Add(name);
} }
@ -43,20 +43,21 @@ namespace MudEngine.GameManagement
return temp; return temp;
} }
public string GetCommand(object Parameter) public static IGameCommand GetCommand(string command)
{ {
List<object> objectList = (List<object>)Parameter; if (IsValidCommand(command))
foreach (object obj in objectList)
{ {
if (obj is string) foreach (IGameCommand cmd in CommandCollection.Values)
return (string)obj; {
if (cmd.Name.ToLower() == command.ToLower())
return cmd;
}
} }
return null; return null;
} }
public bool IsValidCommand(string Name) public static bool IsValidCommand(string Name)
{ {
if (CommandCollection.ContainsKey(Name.ToLower())) if (CommandCollection.ContainsKey(Name.ToLower()))
return true; return true;
@ -75,11 +76,13 @@ namespace MudEngine.GameManagement
if (Game.IsDebug) if (Game.IsDebug)
Log.Write("Executing command: " + command); Log.Write("Executing command: " + command);
foreach (string key in CommandCollection.Keys) foreach (string key in CommandEngine.CommandCollection.Keys)
{ {
if (commandKey.ToLower().Contains(key.ToLower())) if (commandKey.ToLower().Contains(key.ToLower()))
{ {
return player.CommandSystem._Commands[key].Execute(command, player); IGameCommand cmd = CommandEngine.CommandCollection[key];
return cmd.Execute(command, player);
//return player.CommandSystem._Commands[key].Execute(command, player);
//return player.Commands.ExecuteCommand[key.ToLower()]Execute(command, player); //return player.Commands.ExecuteCommand[key.ToLower()]Execute(command, player);
} }
} }
@ -87,7 +90,7 @@ namespace MudEngine.GameManagement
return new CommandResults(); return new CommandResults();
} }
public void LoadBaseCommands() public static void LoadBaseCommands()
{ {
LoadCommandLibrary(Assembly.GetExecutingAssembly(), true); LoadCommandLibrary(Assembly.GetExecutingAssembly(), true);
} }
@ -98,12 +101,12 @@ namespace MudEngine.GameManagement
/// commands dictionary for use with the project /// commands dictionary for use with the project
/// </summary> /// </summary>
/// <param name="CommandLibrary"></param> /// <param name="CommandLibrary"></param>
public void LoadCommandLibrary() public static void LoadCommandLibrary()
{ {
LoadCommandLibrary(Assembly.GetExecutingAssembly()); LoadCommandLibrary(Assembly.GetExecutingAssembly());
} }
public void LoadCommandLibrary(string libraryFilename) public static void LoadCommandLibrary(string libraryFilename)
{ {
if (System.IO.File.Exists(libraryFilename)) if (System.IO.File.Exists(libraryFilename))
{ {
@ -112,18 +115,18 @@ namespace MudEngine.GameManagement
} }
} }
public void LoadCommandLibrary(List<Assembly> commandLibraries) public static void LoadCommandLibrary(List<Assembly> commandLibraries)
{ {
foreach (Assembly lib in commandLibraries) foreach (Assembly lib in commandLibraries)
LoadCommandLibrary(lib); LoadCommandLibrary(lib);
} }
public void LoadCommandLibrary(Assembly commandLibrary) public static void LoadCommandLibrary(Assembly commandLibrary)
{ {
LoadCommandLibrary(commandLibrary, false); LoadCommandLibrary(commandLibrary, false);
} }
public void LoadCommandLibrary(Assembly commandLibrary, bool purgeOldCommands) public static void LoadCommandLibrary(Assembly commandLibrary, bool purgeOldCommands)
{ {
//no assembly passed for whatever reason, don't attempt to enumerate through it. //no assembly passed for whatever reason, don't attempt to enumerate through it.
if (commandLibrary == null) if (commandLibrary == null)
@ -165,7 +168,7 @@ namespace MudEngine.GameManagement
} }
} }
public void ClearCommands() public static void ClearCommands()
{ {
CommandCollection = new Dictionary<string, IGameCommand>(); CommandCollection = new Dictionary<string, IGameCommand>();
} }

View file

@ -238,12 +238,31 @@ namespace MudEngine.GameManagement
/// </summary> /// </summary>
public bool Start() public bool Start()
{ {
Log.Write("Starting Game..."); Log.Write("Game Initializing...");
//Setup the scripting engine and load our script library //Setup the scripting engine and load our script library
scriptEngine.Initialize(); scriptEngine.Initialize();
Log.Write("Initializing location..."); /*
* If a custom player script is loaded in the script engine, then the base commands are
* loaded when the script is instanced automatically. If there is no script then these
* don't get loaded and will need to be forced.
* This prevents a duplicate "Loading Commands" message in the server console if the
* player script exists and pre-loads the commands during script instancing in ScriptEngine.Initialize()
*/
Log.Write("Initializing Command Engine...");
if ((CommandEngine.CommandCollection == null) || (CommandEngine.CommandCollection.Count == 0))
CommandEngine.LoadBaseCommands();
if (IsDebug)
{
foreach (string command in CommandEngine.CommandCollection.Keys)
Log.Write("Command Loaded: " + command);
}
//See if we have an Initial Realm set //See if we have an Initial Realm set
//TODO: Check for saved Realm files and load
Log.Write("Initializing World...");
foreach (Realm r in RealmCollection) foreach (Realm r in RealmCollection)
{ {
if (r.IsInitialRealm) if (r.IsInitialRealm)
@ -260,12 +279,14 @@ namespace MudEngine.GameManagement
return false; return false;
} }
else else
Log.Write("Initial Location defined -> " + InitialRealm.Name + "." + InitialRealm.InitialZone.Name + "." + InitialRealm.InitialZone.InitialRoom.Name); Log.Write("Initial Location loaded-> " + InitialRealm.Name + "." + InitialRealm.InitialZone.Name + "." + InitialRealm.InitialZone.InitialRoom.Name);
Log.Write("Starting Server...");
//Start the Telnet server //Start the Telnet server
if (IsMultiplayer) if (IsMultiplayer)
{
Log.Write("Starting Server...");
this.StartServer(); this.StartServer();
}
//Game is running now. //Game is running now.
IsRunning = true; IsRunning = true;

View file

@ -125,12 +125,18 @@ namespace MudEngine.GameObjects.Characters
//TODO: Check the Room/Zone/Realm to see if anything needs to occure during travel. //TODO: Check the Room/Zone/Realm to see if anything needs to occure during travel.
} }
public String ExecuteCommand(string command) public void ExecuteCommand(string command)
{ {
//TODO: Character class can handle a lot of the command management here, checking various things prior to sending //TODO: Character class can handle a lot of the command management here, checking various things prior to sending
//the command off to the command engine for execution. //the command off to the command engine for execution.
CommandResults result = CommandSystem.ExecuteCommand(command, this); CommandSystem.ExecuteCommand(command, this);
Send(""); //Blank line to help readability.
//Now that the command has been executed, restore the Command: message
Send("Command: ", false);
/* No longer needed due to player.send() sending content to the player.
if (result.Result != null) if (result.Result != null)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -141,7 +147,7 @@ namespace MudEngine.GameObjects.Characters
} }
return sb.ToString(); return sb.ToString();
} }
return ""; */
} }
internal void Initialize() internal void Initialize()
@ -153,26 +159,27 @@ namespace MudEngine.GameObjects.Characters
Log.Write("Loading internal game commands..."); Log.Write("Loading internal game commands...");
//Loads the MudEngine Game Commands //Loads the MudEngine Game Commands
CommandSystem.LoadBaseCommands(); //CommandSystem.LoadBaseCommands();
//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)
{ {
foreach (string command in CommandSystem.GetCommands()) foreach (string command in CommandEngine.GetCommands())
{ {
Log.Write("Command loaded: " + command); Log.Write("Command loaded: " + command);
} }
} }
string result = ExecuteCommand("Login"); ExecuteCommand("Login");
//Set the players initial room
CurrentRoom = ActiveGame.InitialRealm.InitialZone.InitialRoom; CurrentRoom = ActiveGame.InitialRealm.InitialZone.InitialRoom;
} }
internal void Receive(string data) internal void Receive(string data)
{ {
data = ExecuteCommand(data); //data = ExecuteCommand(data);
Send(data); ExecuteCommand(data);
//Send(data); //Results no longer returned as Player.Send() is used by the commands now.
if (!ActiveGame.IsRunning) if (!ActiveGame.IsRunning)
Disconnect(); Disconnect();
} }
@ -190,7 +197,10 @@ namespace MudEngine.GameObjects.Characters
if (newLine) if (newLine)
data += "\n\r"; data += "\n\r";
client.Send(encoding.GetBytes(data)); if (ActiveGame.IsMultiplayer)
client.Send(encoding.GetBytes(data));
else
Console.Write(data);
} }
catch (Exception) catch (Exception)
{ {

View file

@ -79,6 +79,7 @@ namespace MudEngine.Networking
} while (sub < 0); } while (sub < 0);
players[sub].client = server.Accept(); players[sub].client = server.Accept();
players[sub].IsActive = true; players[sub].IsActive = true;
players[sub].IsControlled = true;
clientThreads[sub] = new Thread(ReceiveThread); clientThreads[sub] = new Thread(ReceiveThread);
clientThreads[sub].Start((object)sub); clientThreads[sub].Start((object)sub);
} }

View file

@ -194,6 +194,7 @@ namespace MudEngine.Scripting
{ {
if (_ScriptTypes == ScriptTypes.Assembly) if (_ScriptTypes == ScriptTypes.Assembly)
{ {
Log.Write("Loading Assembly based scripts...");
InitializeAssembly(); InitializeAssembly();
} }
else else
@ -203,6 +204,8 @@ namespace MudEngine.Scripting
foreach (Assembly assembly in _AssemblyCollection) foreach (Assembly assembly in _AssemblyCollection)
{ {
Log.Write("Checking " + Path.GetFileName(assembly.Location) + " for scripts...");
foreach (Type t in assembly.GetTypes()) foreach (Type t in assembly.GetTypes())
{ {
if (t.BaseType == null) if (t.BaseType == null)
@ -210,6 +213,7 @@ namespace MudEngine.Scripting
if (t.BaseType.Name == "BaseObject") if (t.BaseType.Name == "BaseObject")
{ {
GameObjects.Add(new GameObject(Activator.CreateInstance(t, new object[] {_Game}), t.Name)); GameObjects.Add(new GameObject(Activator.CreateInstance(t, new object[] {_Game}), t.Name));
Log.Write(t.Name + " script loaded.");
continue; continue;
} }
else if (t.BaseType.Name == "BaseCharacter") else if (t.BaseType.Name == "BaseCharacter")
@ -217,6 +221,7 @@ namespace MudEngine.Scripting
GameObject obj = new GameObject(Activator.CreateInstance(t, new object[] {_Game}), t.Name); GameObject obj = new GameObject(Activator.CreateInstance(t, new object[] {_Game}), t.Name);
GameObjects.Add(obj); GameObjects.Add(obj);
obj.GetProperty().CurrentRoom = _Game.InitialRealm.InitialZone.InitialRoom; obj.GetProperty().CurrentRoom = _Game.InitialRealm.InitialZone.InitialRoom;
Log.Write(t.Name + " script loaded.");
continue; continue;
} }
} }
@ -234,18 +239,21 @@ namespace MudEngine.Scripting
if (libraries.Length == 0) if (libraries.Length == 0)
{ {
Log.Write("Failed to load Script Assembly!"); Log.Write("No possible script libraries found.");
return; return;
} }
foreach (string library in libraries) foreach (string library in libraries)
{
Log.Write("Found possible script libary: " + Path.GetFileName(library));
_AssemblyCollection.Add(Assembly.LoadFile(library)); _AssemblyCollection.Add(Assembly.LoadFile(library));
}
_AssemblyCollection.Add(Assembly.GetExecutingAssembly()); _AssemblyCollection.Add(Assembly.GetExecutingAssembly());
} }
private void InitializeSourceFiles() private void InitializeSourceFiles()
{ {
Log.Write("Source file scripts is not supported! Please change the script engine settings to load pre-compiled Assemblies!");
} }
public GameObject GetObject(string objectName) public GameObject GetObject(string objectName)

View file

@ -42,7 +42,8 @@ namespace MUDGame
Room bedroom = new Room(game); Room bedroom = new Room(game);
bedroom.Name = "Bedroom"; bedroom.Name = "Bedroom";
bedroom.Description = "This is your bedroom, it's small but comfortable. You have a bed, a book shelf and a rug on the floor.\nYou may walk to the WEST to find you Closet."; bedroom.DetailedDescription.Add("This is your bedroom, it's small but comfortable. You have a bed, a book shelf and a rug on the floor.");
bedroom.DetailedDescription.Add("You may walk to the WEST to find you Closet.");
bedroom.Zone = zone.Name; bedroom.Zone = zone.Name;
bedroom.Realm = realm.Name; bedroom.Realm = realm.Name;
bedroom.IsInitialRoom = true; bedroom.IsInitialRoom = true;
@ -50,7 +51,8 @@ namespace MUDGame
Room closet = new Room(game); Room closet = new Room(game);
closet.Name = "Closet"; closet.Name = "Closet";
closet.Description = "Your closet contains clothing and some shoes.\nYou may walk to your EAST to find your Room."; closet.DetailedDescription.Add("Your closet contains clothing and some shoes.");
closet.DetailedDescription.Add("You may walk to your EAST to find your Room.");
closet.Zone = zone.Name; closet.Zone = zone.Name;
closet.Realm = realm.Name; closet.Realm = realm.Name;
zone.AddRoom(closet); zone.AddRoom(closet);

View file

@ -57,17 +57,15 @@ namespace MUDGame
Console.WriteLine("Available Commands are\n Look\n Exit\n Walk 'direction' where direction = north/south/east/west/up/down\n"); Console.WriteLine("Available Commands are\n Look\n Exit\n Walk 'direction' where direction = north/south/east/west/up/down\n");
//Invoke the Look command so the player knows whats around him/her //Invoke the Look command so the player knows whats around him/her
Console.WriteLine(player.ExecuteCommand("Look")); player.ExecuteCommand("Look"); //Broken? has not been tested since CommandEngine changes.
while (game.IsRunning) while (game.IsRunning)
{ {
/* No longer needed as player.ExecuteCommand() will place this for us.
Console.Write("Command: "); Console.Write("Command: ");
Console.WriteLine(player.ExecuteCommand(Console.ReadLine())); */
player.ExecuteCommand(Console.ReadLine());
} }
// - Exit command handles this now - game.Shutdown();
Console.WriteLine("Press Enter to exit.");
Console.ReadKey();
} }
} }
} }

View file

@ -20,7 +20,7 @@ namespace MudServer
realm.BuildZeroth(); realm.BuildZeroth();
BaseCharacter serverAdmin = new BaseCharacter(game); //BaseCharacter serverAdmin = new BaseCharacter(game);
//Setup the game //Setup the game
game.AutoSave = true; game.AutoSave = true;
@ -39,7 +39,7 @@ namespace MudServer
game.ServerType = ProtocolType.Tcp; game.ServerType = ProtocolType.Tcp;
game.ServerPort = 555; game.ServerPort = 555;
game.MaximumPlayers = 1000; game.MaximumPlayers = 1000;
Game.IsDebug = true; Game.IsDebug = false;
game.Start(); game.Start();