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