//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 { /// /// Manages all of the projects settings. /// [XmlInclude(typeof(StartingLocation))] [XmlInclude(typeof(Currency))] public class Game { public enum TimeOfDayOptions { AlwaysDay, AlwaysNight, Transition, } /// /// Gets or Sets if this game is currently running. /// [Browsable(false)] public bool IsRunning { get; internal set; } /// /// Gets or Sets if this game is running in debug mode. Additional information is sent to the log if enabled. /// 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.")] /// /// Gets or Sets the name of the company /// 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")] /// /// Gets or Sets the companies website for this project /// 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")] /// /// Gets or Sets if the game autosaves when the player changes locations. /// public bool AutoSave { get; set; } [Category("Project Settings")] [Description("Hide Room names from being outputted to the console.")] /// /// Gets or Sets if room names are hidden during console output. /// public bool HideRoomNames { get; set; } /// /// Gets or Sets what time of day the world is currently in. /// [Category("Day Management")] [Description("Set what time of day the world will take place in.")] public TimeOfDayOptions TimeOfDay { get; set; } /// /// Gets or Sets how long in minutes it takes to transition from day to night. /// [Category("Day Management")] [Description("Set how long in minutes it takes to transition from day to night.")] public int TimeOfDayTransition { get; set; } /// /// Gets or Sets how long in minutes a day lasts in the game world. /// [Category("Day Management")] [Description("Sets how long in minutes a day lasts in the game world.")] public int DayLength { get; set; } /// /// Gets or Sets the current working version of the game. /// [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. /// /// 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. /// [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 CurrencyList { get; set; } /// /// Gets or Sets the path to the current project /// [Browsable(false)] public string ProjectPath { get; set; } [Category("Environment Settings")] [ReadOnly(true)] public Realm InitialRealm { get; private set; } /// /// Gets the collection of Realms currently stored in the Game. /// public List 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(); scriptEngine = new Scripting.ScriptEngine(this); RealmCollection = new List(); //PlayerCollection = new List(); GameTitle = "New Game"; _Filename = "Game.xml"; BaseCurrencyAmount = 1; BaseCurrencyName = "Copper"; IsMultiplayer = true; //default. } /// /// Starts the game. /// 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 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() { //This is handled by the Game() Constructor //PlayerCollection = new List(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(); } } }