Made PlayerManager enumerable.

This commit is contained in:
Justin Aquadro 2011-08-14 16:27:52 +00:00
parent ca56f70379
commit ac9c88773c
6 changed files with 334 additions and 10 deletions

View file

@ -12,7 +12,7 @@ namespace Substrate
/// <summary> /// <summary>
/// Represents an Alpha-compatible interface for globally managing chunks. /// Represents an Alpha-compatible interface for globally managing chunks.
/// </summary> /// </summary>
public class AlphaChunkManager : IChunkManager public class AlphaChunkManager : IChunkManager, IEnumerable<ChunkRef>
{ {
private string _mapPath; private string _mapPath;

View file

@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using Substrate.Nbt;
namespace Substrate namespace Substrate
{ {
using Nbt; /// <summary>
/// Provides named id values for known block types.
/// </summary>
public static class BlockType public static class BlockType
{ {
public const int AIR = 0; public const int AIR = 0;
@ -107,20 +108,59 @@ namespace Substrate
public const int TRAPDOOR = 96; public const int TRAPDOOR = 96;
} }
/// <summary>
/// Represents the physical state of a block, such as solid or fluid.
/// </summary>
public enum BlockState public enum BlockState
{ {
/// <summary>
/// A solid state that stops movement.
/// </summary>
SOLID, SOLID,
/// <summary>
/// A nonsolid state that can be passed through.
/// </summary>
NONSOLID, NONSOLID,
/// <summary>
/// A fluid state that flows and impedes movement.
/// </summary>
FLUID FLUID
} }
/// <summary>
/// Provides information on a specific type of block.
/// </summary>
/// <remarks>By default, all known MC block types are already defined and registered, assuming Substrate
/// is up to date with the current MC version. All unknown blocks are given a default type and unregistered status.
/// New block types may be created and used at runtime, and will automatically populate various static lookup tables
/// in the <see cref="BlockInfo"/> class.</remarks>
public class BlockInfo public class BlockInfo
{ {
/// <summary>
/// The maximum number of sequential blocks starting at 0 that can be registered.
/// </summary>
public const int MAX_BLOCKS = 256; public const int MAX_BLOCKS = 256;
/// <summary>
/// The maximum opacity value that can be assigned to a block (fully opaque).
/// </summary>
public const int MAX_OPACITY = 15; public const int MAX_OPACITY = 15;
/// <summary>
/// The minimum opacity value that can be assigned to a block (fully transparent).
/// </summary>
public const int MIN_OPACITY = 0; public const int MIN_OPACITY = 0;
/// <summary>
/// The maximum luminance value that can be assigned to a block.
/// </summary>
public const int MAX_LUMINANCE = 15; public const int MAX_LUMINANCE = 15;
/// <summary>
/// The minimum luminance value that can be assigned to a block.
/// </summary>
public const int MIN_LUMINANCE = 0; public const int MIN_LUMINANCE = 0;
private static readonly BlockInfo[] _blockTable; private static readonly BlockInfo[] _blockTable;
@ -193,61 +233,100 @@ namespace Substrate
private static readonly CacheTableArray<int> _opacityTableCache; private static readonly CacheTableArray<int> _opacityTableCache;
private static readonly CacheTableArray<int> _luminanceTableCache; private static readonly CacheTableArray<int> _luminanceTableCache;
/// <summary>
/// Gets the lookup table for id-to-info values.
/// </summary>
public static ICacheTable<BlockInfo> BlockTable public static ICacheTable<BlockInfo> BlockTable
{ {
get { return _blockTableCache; } get { return _blockTableCache; }
} }
/// <summary>
/// Gets the lookup table for id-to-opacity values.
/// </summary>
public static ICacheTable<int> OpacityTable public static ICacheTable<int> OpacityTable
{ {
get { return _opacityTableCache; } get { return _opacityTableCache; }
} }
/// <summary>
/// Gets the lookup table for id-to-luminance values.
/// </summary>
public static ICacheTable<int> LuminanceTable public static ICacheTable<int> LuminanceTable
{ {
get { return _luminanceTableCache; } get { return _luminanceTableCache; }
} }
/// <summary>
/// Get's the block's Id.
/// </summary>
public int ID public int ID
{ {
get { return _id; } get { return _id; }
} }
/// <summary>
/// Get's the name of the block type.
/// </summary>
public string Name public string Name
{ {
get { return _name; } get { return _name; }
} }
/// <summary>
/// Gets the block's opacity value. An opacity of 0 is fully transparent to light.
/// </summary>
public int Opacity public int Opacity
{ {
get { return _opacity; } get { return _opacity; }
} }
/// <summary>
/// Gets the block's luminance value.
/// </summary>
/// <remarks>Blocks with luminance act as light sources and transmit light to other blocks.</remarks>
public int Luminance public int Luminance
{ {
get { return _luminance; } get { return _luminance; }
} }
/// <summary>
/// Checks whether the block transmits light to neighboring blocks.
/// </summary>
/// <remarks>A block may stop the transmission of light, but still be illuminated.</remarks>
public bool TransmitsLight public bool TransmitsLight
{ {
get { return _transmitLight; } get { return _transmitLight; }
} }
/// <summary>
/// Checks whether the block partially or fully blocks the transmission of light.
/// </summary>
public bool ObscuresLight public bool ObscuresLight
{ {
get { return _opacity > MIN_OPACITY || !_transmitLight; } get { return _opacity > MIN_OPACITY || !_transmitLight; }
} }
/// <summary>
/// Checks whether the block stops fluid from passing through it.
/// </summary>
/// <remarks>A block that does not block fluids will be destroyed by fluid.</remarks>
public bool BlocksFluid public bool BlocksFluid
{ {
get { return _blocksFluid; } get { return _blocksFluid; }
} }
/// <summary>
/// Gets the block's physical state type.
/// </summary>
public BlockState State public BlockState State
{ {
get { return _state; } get { return _state; }
} }
/// <summary>
/// Checks whether this block type has been registered as a known type.
/// </summary>
public bool Registered public bool Registered
{ {
get { return _registered; } get { return _registered; }
@ -260,6 +339,12 @@ namespace Substrate
_blockTable[_id] = this; _blockTable[_id] = this;
} }
/// <summary>
/// Constructs a new <see cref="BlockInfo"/> record for a given block id and name.
/// </summary>
/// <param name="id">The id of the block.</param>
/// <param name="name">The name of the block.</param>
/// <remarks>All user-constructed <see cref="BlockInfo"/> objects are registered automatically.</remarks>
public BlockInfo (int id, string name) public BlockInfo (int id, string name)
{ {
_id = id; _id = id;
@ -268,6 +353,11 @@ namespace Substrate
_registered = true; _registered = true;
} }
/// <summary>
/// Sets a new opacity value for this block type.
/// </summary>
/// <param name="opacity">A new opacity value.</param>
/// <returns>The object instance used to invoke this method.</returns>
public BlockInfo SetOpacity (int opacity) public BlockInfo SetOpacity (int opacity)
{ {
_opacity = MIN_OPACITY + opacity; _opacity = MIN_OPACITY + opacity;
@ -283,6 +373,11 @@ namespace Substrate
return this; return this;
} }
/// <summary>
/// Sets a new luminance value for this block type.
/// </summary>
/// <param name="luminance">A new luminance value.</param>
/// <returns>The object instance used to invoke this method.</returns>
public BlockInfo SetLuminance (int luminance) public BlockInfo SetLuminance (int luminance)
{ {
_luminance = luminance; _luminance = luminance;
@ -290,18 +385,35 @@ namespace Substrate
return this; return this;
} }
/// <summary>
/// Sets whether or not this block type will transmit light to neigboring blocks.
/// </summary>
/// <param name="transmit">True if this block type can transmit light to neighbors, false otherwise.</param>
/// <returns>The object instance used to invoke this method.</returns>
public BlockInfo SetLightTransmission (bool transmit) public BlockInfo SetLightTransmission (bool transmit)
{ {
_transmitLight = transmit; _transmitLight = transmit;
return this; return this;
} }
/// <summary>
/// Sets limitations on what data values are considered valid for this block type.
/// </summary>
/// <param name="low">The lowest valid integer value.</param>
/// <param name="high">The highest valid integer value.</param>
/// <param name="bitmask">A mask representing which bits are interpreted as a bitmask in the data value.</param>
/// <returns>The object instance used to invoke this method.</returns>
public BlockInfo SetDataLimits (int low, int high, int bitmask) public BlockInfo SetDataLimits (int low, int high, int bitmask)
{ {
_dataLimits = new DataLimits(low, high, bitmask); _dataLimits = new DataLimits(low, high, bitmask);
return this; return this;
} }
/// <summary>
/// Sets the physical state of the block type.
/// </summary>
/// <param name="state">A physical state.</param>
/// <returns>The object instance used to invoke this method.</returns>
public BlockInfo SetState (BlockState state) public BlockInfo SetState (BlockState state)
{ {
_state = state; _state = state;
@ -316,12 +428,23 @@ namespace Substrate
return this; return this;
} }
/// <summary>
/// Sets whether or not this block type blocks fluids.
/// </summary>
/// <param name="blocks">True if this block type blocks fluids, false otherwise.</param>
/// <returns>The object instance used to invoke this method.</returns>
public BlockInfo SetBlocksFluid (bool blocks) public BlockInfo SetBlocksFluid (bool blocks)
{ {
_blocksFluid = blocks; _blocksFluid = blocks;
return this; return this;
} }
/// <summary>
/// Tests if the given data value is valid for this block type.
/// </summary>
/// <param name="data">A data value to test.</param>
/// <returns>True if the data value is valid, false otherwise.</returns>
/// <remarks>This method uses internal information set by <see cref="SetDataLimits"/>.</remarks>
public bool TestData (int data) public bool TestData (int data)
{ {
if (_dataLimits == null) { if (_dataLimits == null) {
@ -617,19 +740,36 @@ namespace Substrate
} }
} }
/// <summary>
/// An extended <see cref="BlockInfo"/> that includes <see cref="TileEntity"/> information.
/// </summary>
public class BlockInfoEx : BlockInfo public class BlockInfoEx : BlockInfo
{ {
private string _tileEntityName; private string _tileEntityName;
/// <summary>
/// Gets the name of the <see cref="TileEntity"/> type associated with this block type.
/// </summary>
public string TileEntityName public string TileEntityName
{ {
get { return _tileEntityName; } get { return _tileEntityName; }
} }
public BlockInfoEx (int id) : base(id) { } internal BlockInfoEx (int id) : base(id) { }
/// <summary>
/// Constructs a new <see cref="BlockInfoEx"/> with a given block id and name.
/// </summary>
/// <param name="id">The id of the block type.</param>
/// <param name="name">The name of the block type.</param>
public BlockInfoEx (int id, string name) : base(id, name) { } public BlockInfoEx (int id, string name) : base(id, name) { }
/// <summary>
/// Sets the name of the <see cref="TileEntity"/> type associated with this block type.
/// </summary>
/// <param name="name">The name of a registered <see cref="TileEntity"/> type.</param>
/// <returns>The object instance used to invoke this method.</returns>
/// <seealso cref="TileEntityFactory"/>
public BlockInfo SetTileEntity (string name) { public BlockInfo SetTileEntity (string name) {
_tileEntityName = name; _tileEntityName = name;
return this; return this;

View file

@ -23,5 +23,14 @@ namespace Substrate.Core
string file = name + ".dat"; string file = name + ".dat";
FileName = Path.Combine(path, file); FileName = Path.Combine(path, file);
} }
public static string NameFromFilename (string filename)
{
if (filename.EndsWith(".dat")) {
return filename.Remove(filename.Length - 4);
}
return filename;
}
} }
} }

View file

@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using Substrate.Nbt;
namespace Substrate namespace Substrate
{ {
using Nbt; /// <summary>
/// Provides named id values for known item types.
/// </summary>
public static class ItemType public static class ItemType
{ {
public const int IRON_SHOVEL = 256; public const int IRON_SHOVEL = 256;
@ -116,6 +117,13 @@ namespace Substrate
public const int GREEN_MUSIC_DISC = 2257; public const int GREEN_MUSIC_DISC = 2257;
} }
/// <summary>
/// Provides information on a specific type of item.
/// </summary>
/// <remarks>By default, all known MC item types are already defined and registered, assuming Substrate
/// is up to date with the current MC version.
/// New item types may be created and used at runtime, and will automatically populate various static lookup tables
/// in the <see cref="ItemInfo"/> class.</remarks>
public class ItemInfo public class ItemInfo
{ {
private static Random _rand = new Random(); private static Random _rand = new Random();
@ -150,32 +158,53 @@ namespace Substrate
private static readonly CacheTableDict<ItemInfo> _itemTableCache; private static readonly CacheTableDict<ItemInfo> _itemTableCache;
/// <summary>
/// Gets the lookup table for id-to-info values.
/// </summary>
public static ICacheTable<ItemInfo> ItemTable public static ICacheTable<ItemInfo> ItemTable
{ {
get { return _itemTableCache; } get { return _itemTableCache; }
} }
/// <summary>
/// Gets the id of the item type.
/// </summary>
public int ID public int ID
{ {
get { return _id; } get { return _id; }
} }
/// <summary>
/// Gets the name of the item type.
/// </summary>
public string Name public string Name
{ {
get { return _name; } get { return _name; }
} }
/// <summary>
/// Gets the maximum stack size allowed for this item type.
/// </summary>
public int StackSize public int StackSize
{ {
get { return _stack; } get { return _stack; }
} }
/// <summary>
/// Constructs a new <see cref="ItemInfo"/> record for the given item id.
/// </summary>
/// <param name="id">The id of an item type.</param>
public ItemInfo (int id) public ItemInfo (int id)
{ {
_id = id; _id = id;
_itemTable[_id] = this; _itemTable[_id] = this;
} }
/// <summary>
/// Constructs a new <see cref="ItemInfo"/> record for the given item id and name.
/// </summary>
/// <param name="id">The id of an item type.</param>
/// <param name="name">The name of an item type.</param>
public ItemInfo (int id, string name) public ItemInfo (int id, string name)
{ {
_id = id; _id = id;
@ -183,12 +212,21 @@ namespace Substrate
_itemTable[_id] = this; _itemTable[_id] = this;
} }
/// <summary>
/// Sets the maximum stack size for this item type.
/// </summary>
/// <param name="stack">A stack size between 1 and 64, inclusive.</param>
/// <returns>The object instance used to invoke this method.</returns>
public ItemInfo SetStackSize (int stack) public ItemInfo SetStackSize (int stack)
{ {
_stack = stack; _stack = stack;
return this; return this;
} }
/// <summary>
/// Chooses a registered item type at random and returns it.
/// </summary>
/// <returns></returns>
public static ItemInfo GetRandomItem () public static ItemInfo GetRandomItem ()
{ {
List<ItemInfo> list = new List<ItemInfo>(_itemTable.Values); List<ItemInfo> list = new List<ItemInfo>(_itemTable.Values);

View file

@ -44,6 +44,7 @@ namespace Substrate
private int? _spawnZ; private int? _spawnZ;
private string _world; private string _world;
private string _name;
private ItemCollection _inventory; private ItemCollection _inventory;
@ -141,6 +142,15 @@ namespace Substrate
set { _world = value; } set { _world = value; }
} }
/// <summary>
/// Gets or sets the name that is used when the player is read or written from a <see cref="PlayerManager"/>.
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; }
}
/// <summary> /// <summary>
/// Creates a new <see cref="Player"/> object with reasonable default values. /// Creates a new <see cref="Player"/> object with reasonable default values.
/// </summary> /// </summary>

View file

@ -4,6 +4,8 @@ using System.Text;
using System.IO; using System.IO;
using Substrate.Core; using Substrate.Core;
using Substrate.Nbt; using Substrate.Nbt;
using System.Text.RegularExpressions;
using System.Collections;
namespace Substrate namespace Substrate
{ {
@ -11,7 +13,7 @@ namespace Substrate
/// Functions to manage multiple <see cref="Player"/> entities and files in multiplayer settings. /// Functions to manage multiple <see cref="Player"/> entities and files in multiplayer settings.
/// </summary> /// </summary>
/// <remarks>This manager is intended for player files stored in standard compressed NBT format.</remarks> /// <remarks>This manager is intended for player files stored in standard compressed NBT format.</remarks>
public class PlayerManager : IPlayerManager public class PlayerManager : IPlayerManager, IEnumerable<Player>
{ {
private string _playerPath; private string _playerPath;
@ -82,7 +84,9 @@ namespace Substrate
} }
try { try {
return new Player().LoadTreeSafe(GetPlayerTree(name).Root); Player p = new Player().LoadTreeSafe(GetPlayerTree(name).Root);
p.Name = name;
return p;
} }
catch (Exception ex) { catch (Exception ex) {
PlayerIOException pex = new PlayerIOException("Could not load player", ex); PlayerIOException pex = new PlayerIOException("Could not load player", ex);
@ -109,6 +113,16 @@ namespace Substrate
} }
} }
/// <summary>
/// Saves a <see cref="Player"/> object's data back to file given the name set in the <see cref="Player"/> object.
/// </summary>
/// <param name="player">The <see cref="Player"/> object containing the data to write back.</param>
/// <exception cref="PlayerIOException">Thrown when the manager cannot write out the player.</exception>
public void SetPlayer (Player player)
{
SetPlayer(player.Name, player);
}
/// <summary> /// <summary>
/// Checks if data for a player with the given name exists. /// Checks if data for a player with the given name exists.
/// </summary> /// </summary>
@ -135,5 +149,118 @@ namespace Substrate
throw pex; throw pex;
} }
} }
#region IEnumerable<Player> Members
/// <summary>
/// Gets an enumerator that iterates through all the chunks in the world.
/// </summary>
/// <returns>An enumerator for this manager.</returns>
public IEnumerator<Player> GetEnumerator ()
{
return new Enumerator(this);
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
{
return new Enumerator(this);
}
#endregion
private class Enumerator : IEnumerator<Player>
{
protected PlayerManager _pm;
protected Queue<string> _names;
protected Player _curPlayer;
public Enumerator (PlayerManager cfm)
{
_pm = cfm;
_names = new Queue<string>();
if (!Directory.Exists(_pm._playerPath)) {
throw new DirectoryNotFoundException();
}
Reset();
}
public bool MoveNext ()
{
if (_names.Count == 0) {
return false;
}
string name = _names.Dequeue();
_curPlayer = _pm.GetPlayer(name);
_curPlayer.Name = name;
return true;
}
public void Reset ()
{
_names.Clear();
_curPlayer = null;
string[] files = Directory.GetFiles(_pm._playerPath);
foreach (string file in files) {
string basename = Path.GetFileName(file);
if (!ParseFileName(basename)) {
continue;
}
_names.Enqueue(PlayerFile.NameFromFilename(basename));
}
}
void IDisposable.Dispose () { }
object IEnumerator.Current
{
get
{
return Current;
}
}
Player IEnumerator<Player>.Current
{
get
{
return Current;
}
}
public Player Current
{
get
{
if (_curPlayer == null) {
throw new InvalidOperationException();
}
return _curPlayer;
}
}
private bool ParseFileName (string filename)
{
Match match = _namePattern.Match(filename);
if (!match.Success) {
return false;
}
return true;
}
protected static Regex _namePattern = new Regex(".+\\.dat$");
}
} }
} }