using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using Substrate.Core; using Substrate.Nbt; using Substrate.Data; namespace Substrate { /// /// An abstract representation of any conforming chunk-based world. /// /// By default, NbtWorld registers handlers to check if a given world can be opened as an or /// a , which are used by 's generic method to automatically /// detect a world's type and open it. /// Advanced implementors can support loading other Nbt-compatible world formats by extending and registering /// an event handler with the event, which will allow the generic method to /// open worlds of the new format. public abstract class NbtWorld { private const string _DATA_DIR = "data"; private string _path; private string _dataDir; /// /// Creates a new instance of an object. /// protected NbtWorld () { _dataDir = _DATA_DIR; } /// /// Gets or sets the path to the directory containing the world. /// public string Path { get { return _path; } set { _path = value; } } /// /// Gets or sets the directory containing data resources, rooted in the world directory. /// public string DataDirectory { get { return _dataDir; } set { _dataDir = value; } } /// /// Gets a reference to this world's object. /// public abstract Level Level { get; } /// /// Gets an for the default dimension. /// /// An tied to the default dimension in this world. public IBlockManager GetBlockManager () { return GetBlockManagerVirt(Dimension.DEFAULT); } /// /// Gets an for the given dimension. /// /// The id of the dimension to look up. /// An tied to the given dimension in this world. public IBlockManager GetBlockManager (int dim) { return GetBlockManagerVirt(dim); } public IBlockManager GetBlockManager (string dim) { return GetBlockManagerVirt(dim); } /// /// Gets an for the default dimension. /// /// An tied to the default dimension in this world. public IChunkManager GetChunkManager () { return GetChunkManagerVirt(Dimension.DEFAULT); } /// /// Gets an for the given dimension. /// /// The id of the dimension to look up. /// An tied to the given dimension in this world. public IChunkManager GetChunkManager (int dim) { return GetChunkManagerVirt(dim); } public IChunkManager GetChunkManager (string dim) { return GetChunkManagerVirt(dim); } /// /// Gets an for maanging players on multiplayer worlds. /// /// An for this world. public IPlayerManager GetPlayerManager () { return GetPlayerManagerVirt(); } /// /// Gets a for managing data resources, such as maps. /// /// A for this world. public DataManager GetDataManager () { return GetDataManagerVirt(); } /// /// Attempts to determine the best matching world type of the given path, and open the world as that type. /// /// The path to the directory containing the world. /// A concrete type, or null if the world cannot be opened or is ambiguos. public static NbtWorld Open (string path) { if (ResolveOpen == null) { return null; } OpenWorldEventArgs eventArgs = new OpenWorldEventArgs(path); ResolveOpen(null, eventArgs); if (eventArgs.HandlerCount != 1) { return null; } foreach (OpenWorldCallback callback in eventArgs.Handlers) { return callback(path); } return null; } /// /// Saves the world's data, and any objects known to have unsaved changes. /// public abstract void Save (); /// /// Raised when is called, used to find a concrete type that can open the world. /// protected static event EventHandler ResolveOpen; #region Covariant Return-Type Helpers /// /// Virtual implementor of . /// /// The given dimension to fetch an for. /// An for the given dimension in the world. protected abstract IBlockManager GetBlockManagerVirt (int dim); /// /// Virtual implementor of . /// /// The given dimension to fetch an for. /// An for the given dimension in the world. protected abstract IChunkManager GetChunkManagerVirt (int dim); protected virtual IBlockManager GetBlockManagerVirt (string dim) { throw new NotImplementedException(); } protected virtual IChunkManager GetChunkManagerVirt (string dim) { throw new NotImplementedException(); } /// /// Virtual implementor of . /// /// An for the given dimension in the world. protected abstract IPlayerManager GetPlayerManagerVirt (); /// /// Virtual implementor of /// /// A for the given dimension in the world. protected virtual DataManager GetDataManagerVirt () { throw new NotImplementedException(); } #endregion static NbtWorld () { ResolveOpen += AnvilWorld.OnResolveOpen; ResolveOpen += BetaWorld.OnResolveOpen; ResolveOpen += AlphaWorld.OnResolveOpen; } } }