muddesigner/MudEngine/GameManagement/Game.cs
Scionwest_cp 793c3cf1e9 MudEngine:
- FileManager.GetDataPath now returns the actual Root directory when Root is requested rather than Root/Projects. That was considered Root for the older Designer.
 - CommandEngine.GetCommands is now a method rather than a property.
 - CommandEngine.LoadAllCommands replaced with CommandEngine.LoadBaseCommands for loading Engine specific Game commands. This is called from within Game.Start. A possible property for disabling default commands could be looked at in the future.
 - CommandEngine.LoadCommandLibrary method added for loading custom user commands. This is fully implemented.
 - CommandEngine.ClearCommands method added for clearing all currently loaded commands.
 - Game.IsDebug static property added.
 - Added additional logging for testing purposes throughout the project. Changing Game.IsDebug to false will remove the majority of the logged messages.
 - Game.IsMultiplayer property added for enabling or disabling the server for Online/Offline support. Fully implemented.
 - Game no longer loads user script libraries as this was being handled already by ScriptEngine.Initialize()
 - Log now caches messages so consoles can print only content that was logged since the last loop. Using Log.FlushMessages() will clear the cached messages allowing each loop to show only the new logged messages.
 - BaseCharacter IsAdmin argument in the constructor has been removed. No longer needed for testing.
 - ScriptEngine can now compile more than 1 script without error.
 - ScriptEngine.Assembly property added for accessing the currently loaded script library. This should be a List<Assembly> in the future for multiple libraries.
 - Removed the last of my BlitScript engine code from ScriptEngine.cs as it was XNA specific. Need to look at StartupObject.cs as I believe that is XNA specific as well and not needed.

MudGame:
 - Renamed MudGame to MudOfflineExample as it will be used for testing the game with Game.IsMultiplayer disabled. Makes testing easier then needing to stop/restart the server and connect via telnet constantly.

MudServer:
 - Added MudServer project. This is a dedicated server that runs with Game.IsMultiplayer enabled. Developers can connect to it via telnet clients. All engine game commands are implemented.
 - MudServer includes bin/Debug/Scripts.dll, which is a compiled library of scripts generated via MudCompiler. MudEngine.Game handles loading the library and there is no additional code required by the developers to implement their libraries into their games provided the name is 'Scripts.dll'
2010-07-27 16:31:50 -07:00

334 lines
11 KiB
C#

//Microsoft .NET Framework
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
//MUD Engine
using MudEngine.FileSystem;
using MudEngine.GameObjects;
using MudEngine.GameObjects.Characters;
using MudEngine.GameObjects.Environment;
namespace MudEngine.GameManagement
{
/// <summary>
/// Manages all of the projects settings.
/// </summary>
[XmlInclude(typeof(StartingLocation))]
[XmlInclude(typeof(Currency))]
public class Game
{
public enum TimeOfDayOptions
{
AlwaysDay,
AlwaysNight,
Transition,
}
/// <summary>
/// Gets or Sets if this game is currently running.
/// </summary>
[Browsable(false)]
public bool IsRunning { get; internal set; }
/// <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; }
public bool IsMultiplayer { get; set; }
[Category("Company Settings")]
[Description("The name of the Company or Author building the game.")]
/// <summary>
/// Gets or Sets the name of the company
/// </summary>
public string CompanyName { get; set; }
[Category("Company Settings")]
[Description("The website URL that a player can visit to view additional information related to the game")]
/// <summary>
/// Gets or Sets the companies website for this project
/// </summary>
public string Website { get; set; }
[Category("Project Settings")]
[Description("The name of the game displayed to the users, and title bar of the runtime.")]
public string GameTitle { get; set; }
[Category("Project Settings")]
[Description("Enable or Disable Auto-saving of players when the player travels")]
/// <summary>
/// Gets or Sets if the game autosaves when the player changes locations.
/// </summary>
public bool AutoSave { get; set; }
[Category("Project Settings")]
[Description("Hide Room names from being outputted to the console.")]
/// <summary>
/// Gets or Sets if room names are hidden during console output.
/// </summary>
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>
/// Gets or Sets how long in minutes it takes to transition from day to night.
/// </summary>
[Category("Day Management")]
[Description("Set how long in minutes it takes to transition from day to night.")]
public int TimeOfDayTransition
{
get;
set;
}
/// <summary>
/// Gets or Sets how long in minutes a day lasts in the game world.
/// </summary>
[Category("Day Management")]
[Description("Sets how long in minutes a day lasts in the game world.")]
public int DayLength
{
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")]
[DefaultValue(1)]
[Description("Sets the amount that the base currency is valued at.")]
public uint BaseCurrencyAmount { get; set; }
[Category("Game Currency")]
[DefaultValue("Copper")]
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)]
public List<Currency> CurrencyList { get; set; }
/// <summary>
/// Gets or Sets the path to the current project
/// </summary>
[Browsable(false)]
public string ProjectPath { get; set; }
[Category("Environment Settings")]
[ReadOnly(true)]
public Realm InitialRealm
{
get;
private set;
}
/// <summary>
/// Gets the collection of Realms currently stored in the Game.
/// </summary>
public List<Realm> RealmCollection { get; private set; }
[Browsable(false)]
public string Story
{
get;
set;
}
[Category("Object Setup")]
public string Filename
{
get
{
return _Filename;
}
}
private string _Filename;
public Game()
{
CurrencyList = new List<Currency>();
scriptEngine = new Scripting.ScriptEngine();
RealmCollection = new List<Realm>();
//PlayerCollection = new List<BaseCharacter>();
GameTitle = "New Game";
_Filename = "Game.xml";
BaseCurrencyAmount = 1;
BaseCurrencyName = "Copper";
IsMultiplayer = true; //default.
}
/// <summary>
/// Starts the game.
/// </summary>
public bool Start()
{
Log.Write("Starting Game...");
//Setup the scripting engine and load our script library
scriptEngine.Initialize();
Log.Write("Loading internal game commands...");
//Loads the MudEngine Game Commands
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.
if (Game.IsDebug)
{
foreach (string command in CommandEngine.GetCommands())
{
Log.Write("Command loaded: " + command);
}
}
Log.Write("Initializing location...");
//See if we have an Initial Realm set
foreach (Realm r in RealmCollection)
{
if (r.IsInitialRealm)
{
InitialRealm = r;
break;
}
}
if ((InitialRealm == null) || (InitialRealm.InitialZone == null) || (InitialRealm.InitialZone.InitialRoom == null))
{
Log.Write("ERROR: No initial location defined. Game startup failed!");
return false;
}
else
Log.Write("Initial Location defined -> " + InitialRealm.Name + "." + InitialRealm.InitialZone.Name + "." + InitialRealm.InitialZone.InitialRoom.Name);
Log.Write("Starting Server...");
//Start the Telnet server
if (IsMultiplayer)
this.StartServer();
IsRunning = true;
Log.Write("Game startup complete.");
return true;
}
public void Shutdown()
{
Log.Write("Server shutdown requested...");
//Place ending code here for game shut down.
//TODO: Save content on shutdown.
if (IsMultiplayer)
Server.EndServer();
IsRunning = false;
Log.Write("Shutdown completed...");
}
public void Save(string filename)
{
string directory = Path.GetDirectoryName(filename);
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
FileManager.Save(filename, this);
}
public object Load(string path)
{
string fileName = Path.Combine(path, _Filename);
if (!File.Exists(fileName))
{
return null;
}
return FileManager.Load(fileName, this);
}
public void AddRealm(Realm realm)
{
if (realm.IsInitialRealm)
{
foreach (Realm r in RealmCollection)
{
if (r.IsInitialRealm)
{
r.IsInitialRealm = false;
break;
}
}
}
if (realm.IsInitialRealm)
InitialRealm = realm;
//TODO: Check for duplicate Realms.
RealmCollection.Add(realm);
}
public Realm GetRealm(string realmName)
{
foreach (Realm realm in RealmCollection)
{
if (realm.Name == realmName)
return realm;
}
return null;
}
//TODO: This should be internal only; C# property using get; internal set; so only MudEngine.dll may edit this collection
//public List<BaseCharacter> PlayerCollection;
public BaseCharacter[] PlayerCollection;
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()
{
//PlayerCollection = new List<BaseCharacter>(MaximumPlayers);
PlayerCollection = new BaseCharacter[MaximumPlayers];
for (int i = 0; i < MaximumPlayers; i++)
PlayerCollection[i] = new BaseCharacter(this);
Server = new Networking.Server();
Server.Initialize(ServerPort, ref PlayerCollection);
Server.Start();
}
}
}