From 3387386295c80856752c2d3559a720854c613ad0 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Sat, 2 Jul 2011 03:51:48 +0000 Subject: [PATCH] Updated Info classes, updated and documented Player classes. --- .../SubstrateCS/Properties/AssemblyInfo.cs | 4 +- Substrate/SubstrateCS/Source/BlockInfo.cs | 47 +++++-- Substrate/SubstrateCS/Source/BlockManager.cs | 1 + Substrate/SubstrateCS/Source/CacheTable.cs | 84 ++++++++++++ Substrate/SubstrateCS/Source/ChunkManager.cs | 8 +- Substrate/SubstrateCS/Source/Core/NBTFile.cs | 47 +++++-- .../Source/Core/PlayerManagerInterface.cs | 39 ++++++ Substrate/SubstrateCS/Source/Entity.cs | 6 +- .../SubstrateCS/Source/EntityCollection.cs | 93 ++++++++++--- Substrate/SubstrateCS/Source/ItemInfo.cs | 30 +++-- Substrate/SubstrateCS/Source/Level.cs | 2 +- .../SubstrateCS/Source/Nbt/NbtIOException.cs | 48 +++++++ Substrate/SubstrateCS/Source/Player.cs | 114 +++++++++++++--- .../SubstrateCS/Source/PlayerIOException.cs | 46 +++++++ Substrate/SubstrateCS/Source/PlayerManager.cs | 94 ++++++++++--- Substrate/SubstrateCS/Source/RegionManager.cs | 17 +-- Substrate/SubstrateCS/Source/SpawnPoint.cs | 125 ++++++++++++++++++ Substrate/SubstrateCS/Substrate.csproj | 17 ++- 18 files changed, 711 insertions(+), 111 deletions(-) create mode 100644 Substrate/SubstrateCS/Source/CacheTable.cs create mode 100644 Substrate/SubstrateCS/Source/Core/PlayerManagerInterface.cs create mode 100644 Substrate/SubstrateCS/Source/Nbt/NbtIOException.cs create mode 100644 Substrate/SubstrateCS/Source/PlayerIOException.cs create mode 100644 Substrate/SubstrateCS/Source/SpawnPoint.cs diff --git a/Substrate/SubstrateCS/Properties/AssemblyInfo.cs b/Substrate/SubstrateCS/Properties/AssemblyInfo.cs index d03ee62..ba49779 100644 --- a/Substrate/SubstrateCS/Properties/AssemblyInfo.cs +++ b/Substrate/SubstrateCS/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.6.1.0")] -[assembly: AssemblyFileVersion("0.6.1.0")] +[assembly: AssemblyVersion("0.7.0.0")] +[assembly: AssemblyFileVersion("0.7.0.0")] diff --git a/Substrate/SubstrateCS/Source/BlockInfo.cs b/Substrate/SubstrateCS/Source/BlockInfo.cs index 75fc832..0fe59e3 100644 --- a/Substrate/SubstrateCS/Source/BlockInfo.cs +++ b/Substrate/SubstrateCS/Source/BlockInfo.cs @@ -122,11 +122,11 @@ namespace Substrate public const int MAX_LUMINANCE = 15; public const int MIN_LUMINANCE = 0; - private static BlockInfo[] _blockTable; - private static int[] _opacityTable; - private static int[] _luminanceTable; + private static readonly BlockInfo[] _blockTable; + private static readonly int[] _opacityTable; + private static readonly int[] _luminanceTable; - public class ItemCache + private class CacheTableArray : ICacheTable { private T[] _cache; @@ -135,7 +135,7 @@ namespace Substrate get { return _cache[index]; } } - public ItemCache (T[] cache) + public CacheTableArray (T[] cache) { _cache = cache; } @@ -182,18 +182,30 @@ namespace Substrate private int _luminance = MIN_LUMINANCE; private bool _transmitLight = false; private bool _blocksFluid = true; + private bool _registered = false; private BlockState _state = BlockState.SOLID; private DataLimits _dataLimits; - public static ItemCache BlockTable; + private static readonly CacheTableArray _blockTableCache; + private static readonly CacheTableArray _opacityTableCache; + private static readonly CacheTableArray _luminanceTableCache; - public static ItemCache OpacityTable; + public static ICacheTable BlockTable + { + get { return _blockTableCache; } + } - public static ItemCache LuminanceTable; + public static ICacheTable OpacityTable + { + get { return _opacityTableCache; } + } - //public static ItemCache SchemaTable; + public static ICacheTable LuminanceTable + { + get { return _luminanceTableCache; } + } public int ID { @@ -235,9 +247,15 @@ namespace Substrate get { return _state; } } - public BlockInfo (int id) + public bool Registered + { + get { return _registered; } + } + + internal BlockInfo (int id) { _id = id; + _name = "Unknown Block"; _blockTable[_id] = this; } @@ -246,6 +264,7 @@ namespace Substrate _id = id; _name = name; _blockTable[_id] = this; + _registered = true; } public BlockInfo SetOpacity (int opacity) @@ -413,9 +432,9 @@ namespace Substrate _opacityTable = new int[MAX_BLOCKS]; _luminanceTable = new int[MAX_BLOCKS]; - BlockTable = new ItemCache(_blockTable); - OpacityTable = new ItemCache(_opacityTable); - LuminanceTable = new ItemCache(_luminanceTable); + _blockTableCache = new CacheTableArray(_blockTable); + _opacityTableCache = new CacheTableArray(_opacityTable); + _luminanceTableCache = new CacheTableArray(_luminanceTable); Air = new BlockInfo(0, "Air").SetOpacity(0).SetState(BlockState.NONSOLID); Stone = new BlockInfo(1, "Stone"); @@ -516,7 +535,7 @@ namespace Substrate for (int i = 0; i < MAX_BLOCKS; i++) { if (_blockTable[i] == null) { - _blockTable[i] = new BlockInfo(i, "Uknown Block"); + _blockTable[i] = new BlockInfo(i); } } diff --git a/Substrate/SubstrateCS/Source/BlockManager.cs b/Substrate/SubstrateCS/Source/BlockManager.cs index 479c570..0d8a5a8 100644 --- a/Substrate/SubstrateCS/Source/BlockManager.cs +++ b/Substrate/SubstrateCS/Source/BlockManager.cs @@ -25,6 +25,7 @@ namespace Substrate protected IChunkManager _chunkMan; protected ChunkRef _cache; + protected AlphaBlockCollection _blocks; private bool _autoLight = true; private bool _autoFluid = false; diff --git a/Substrate/SubstrateCS/Source/CacheTable.cs b/Substrate/SubstrateCS/Source/CacheTable.cs new file mode 100644 index 0000000..6ce7ac3 --- /dev/null +++ b/Substrate/SubstrateCS/Source/CacheTable.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; + +namespace Substrate +{ + /// + /// Provides read-only indexed access to an underlying resource. + /// + /// The type of the underlying resource. + public interface ICacheTable + { + /// + /// Gets the value at the given index. + /// + /// The index to fetch. + T this[int index] { get; } + } + + /*internal class CacheTableArray : ICacheTable + { + private T[] _cache; + + public T this[int index] + { + get { return _cache[index]; } + } + + public CacheTableArray (T[] cache) + { + _cache = cache; + } + } + + internal class CacheTableDictionary : ICacheTable + { + private Dictionary _cache; + private static Random _rand = new Random(); + + public T this[int index] + { + get + { + T val; + if (_cache.TryGetValue(index, out val)) { + return val; + } + return default(T); + } + } + + public CacheTableDictionary (Dictionary cache) + { + _cache = cache; + } + } + + /// + /// Provides read-only indexed access to an underlying resource. + /// + /// The type of the underlying resource. + public class CacheTable + { + ICacheTable _cache; + + /// + /// Gets the value at the given index. + /// + /// + public T this[int index] + { + get { return _cache[index]; } + } + + internal CacheTable (T[] cache) + { + _cache = new CacheTableArray(cache); + } + + internal CacheTable (Dictionary cache) + { + _cache = new CacheTableDictionary(cache); + } + }*/ +} diff --git a/Substrate/SubstrateCS/Source/ChunkManager.cs b/Substrate/SubstrateCS/Source/ChunkManager.cs index 6970ef4..18155bf 100644 --- a/Substrate/SubstrateCS/Source/ChunkManager.cs +++ b/Substrate/SubstrateCS/Source/ChunkManager.cs @@ -262,7 +262,7 @@ namespace Substrate public IEnumerator GetEnumerator () { - return new ChunkEnumerator(this); + return new Enumerator(this); } #endregion @@ -272,13 +272,13 @@ namespace Substrate System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () { - return new ChunkEnumerator(this); + return new Enumerator(this); } #endregion - public class ChunkEnumerator : IEnumerator + private class Enumerator : IEnumerator { private ChunkManager _cm; @@ -289,7 +289,7 @@ namespace Substrate private int _x = 0; private int _z = -1; - public ChunkEnumerator (ChunkManager cm) + public Enumerator (ChunkManager cm) { _cm = cm; _enum = _cm.GetRegionManager().GetEnumerator(); diff --git a/Substrate/SubstrateCS/Source/Core/NBTFile.cs b/Substrate/SubstrateCS/Source/Core/NBTFile.cs index 8f2fb6a..4995a9d 100644 --- a/Substrate/SubstrateCS/Source/Core/NBTFile.cs +++ b/Substrate/SubstrateCS/Source/Core/NBTFile.cs @@ -21,30 +21,39 @@ namespace Substrate.Core return File.Exists(_filename); } - public bool Delete () + public void Delete () { File.Delete(_filename); - return true; } public virtual Stream GetDataInputStream () { - FileStream fstr = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + try { + FileStream fstr = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - long length = fstr.Seek(0, SeekOrigin.End); - fstr.Seek(0, SeekOrigin.Begin); + long length = fstr.Seek(0, SeekOrigin.End); + fstr.Seek(0, SeekOrigin.Begin); - byte[] data = new byte[length]; - fstr.Read(data, 0, data.Length); + byte[] data = new byte[length]; + fstr.Read(data, 0, data.Length); - fstr.Close(); + fstr.Close(); - return new GZipStream(new MemoryStream(data), CompressionMode.Decompress); + return new GZipStream(new MemoryStream(data), CompressionMode.Decompress); + } + catch (Exception ex) { + throw new NbtIOException("Failed to open compressed NBT data stream for input.", ex); + } } public virtual Stream GetDataOutputStream () { - return new GZipStream(new NBTBuffer(this), CompressionMode.Compress); + try { + return new GZipStream(new NBTBuffer(this), CompressionMode.Compress); + } + catch (Exception ex) { + throw new NbtIOException("Failed to initialize compressed NBT data stream for output.", ex); + } } class NBTBuffer : MemoryStream @@ -59,9 +68,21 @@ namespace Substrate.Core public override void Close () { - FileStream fstr = new FileStream(file._filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); - fstr.Write(this.GetBuffer(), 0, (int)this.Length); - fstr.Close(); + FileStream fstr; + try { + fstr = new FileStream(file._filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); + } + catch (Exception ex) { + throw new NbtIOException("Failed to open NBT data stream for output.", ex); + } + + try { + fstr.Write(this.GetBuffer(), 0, (int)this.Length); + fstr.Close(); + } + catch (Exception ex) { + throw new NbtIOException("Failed to write out NBT data stream.", ex); + } } } diff --git a/Substrate/SubstrateCS/Source/Core/PlayerManagerInterface.cs b/Substrate/SubstrateCS/Source/Core/PlayerManagerInterface.cs new file mode 100644 index 0000000..5c8d7c8 --- /dev/null +++ b/Substrate/SubstrateCS/Source/Core/PlayerManagerInterface.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.Core +{ + /// + /// An interface of basic manipulations on an abstract data store for player data. + /// + public interface IPlayerManager + { + /// + /// Gets a object for the given player from the underlying data store. + /// + /// The name of the player to fetch. + /// A object for the given player, or null if the player could not be found. + Player GetPlayer (string name); + + /// + /// Saves a object's data back to the underlying data store for the given player. + /// + /// The name of the player to write back data for. + /// The object containing data to write back. + void SetPlayer (string name, Player player); + + /// + /// Checks if a player exists in the underlying data store. + /// + /// The name of the player to look up. + /// True if player data was found; false otherwise. + bool PlayerExists (string name); + + /// + /// Deletes a player with the given name from the underlying data store. + /// + /// The name of the player to delete. + void DeletePlayer (string name); + } +} diff --git a/Substrate/SubstrateCS/Source/Entity.cs b/Substrate/SubstrateCS/Source/Entity.cs index 7567135..af55d44 100644 --- a/Substrate/SubstrateCS/Source/Entity.cs +++ b/Substrate/SubstrateCS/Source/Entity.cs @@ -77,7 +77,7 @@ namespace Substrate } /// - /// Gets or sets the reamining air availale to the entity. + /// Gets or sets the remaining air availale to the entity. /// public int Air { @@ -108,7 +108,7 @@ namespace Substrate /// Constructs a new generic by copying fields from another object. /// /// An to copy fields from. - public Entity (Entity e) + protected Entity (Entity e) { _pos = new Vector3(); _pos.X = e._pos.X; @@ -288,7 +288,7 @@ namespace Substrate /// Constructs a new by copying an existing one. /// /// The to copy. - public EntityTyped (EntityTyped e) + protected EntityTyped (EntityTyped e) : base(e) { _id = e._id; diff --git a/Substrate/SubstrateCS/Source/EntityCollection.cs b/Substrate/SubstrateCS/Source/EntityCollection.cs index a03e8ad..2e92563 100644 --- a/Substrate/SubstrateCS/Source/EntityCollection.cs +++ b/Substrate/SubstrateCS/Source/EntityCollection.cs @@ -1,28 +1,42 @@ using System; using System.Collections.Generic; using System.Text; +using Substrate.Nbt; namespace Substrate { - using Nbt; - + /// + /// Functions to query and manage a collection of entities. + /// public class EntityCollection : IEnumerable { private TagNodeList _entities; private bool _dirty; + /// + /// Gets or sets a value indicating whether this collection contains unsaved changes. + /// public bool IsDirty { get { return _dirty; } set { _dirty = value; } } + /// + /// Creates a new around a containing Entity nodes. + /// + /// A containing Entity nodes. public EntityCollection (TagNodeList entities) { _entities = entities; } + /// + /// Gets a list of all entities in the collection that match a given id (type). + /// + /// The id (type) of entities that should be returned. + /// A list of objects matching the given id (type). public List FindAll (string id) { List set = new List(); @@ -46,6 +60,11 @@ namespace Substrate return set; } + /// + /// Gets a list of all entities in the collection that match a given condition. + /// + /// A defining the matching condition. + /// A list of objects matching the given condition. public List FindAll (Predicate match) { List set = new List(); @@ -64,24 +83,25 @@ namespace Substrate return set; } - public bool Add (EntityTyped ent) + /// + /// Adds a to the collection. + /// + /// The object to add. + /// It is up to the developer to ensure that the being added to the collection has a position that + /// is within acceptable range of the collection. transparently back other objects such as + /// objects, which have a well-defined position in global space. The itself has + /// no concept of position and will not enforce constraints on the positions of objects being added. + public void Add (EntityTyped ent) { - /*double xlow = _cx * XDim; - double xhigh = xlow + XDim; - double zlow = _cz * ZDim; - double zhigh = zlow + ZDim; - - Entity.Vector3 pos = ent.Position; - if (!(pos.X >= xlow && pos.X < xhigh && pos.Z >= zlow && pos.Z < zhigh)) { - return false; - }*/ - _entities.Add(ent.BuildTree()); _dirty = true; - - return true; } + /// + /// Removes all entities matching the given id (type) from the collection. + /// + /// The id (type) of entities that should be removed. + /// A count of the number of entities that were removed. public int RemoveAll (string id) { int rem = _entities.RemoveAll(val => @@ -106,6 +126,11 @@ namespace Substrate return rem; } + /// + /// Removes all entities matching the given condition from the collection. + /// + /// A defining the matching condition. + /// A count of the number of entities that were removed. public int RemoveAll (Predicate match) { int rem = _entities.RemoveAll(val => @@ -132,35 +157,50 @@ namespace Substrate #region IEnumerable Members + /// + /// Returns an enumerator that iterates through all entities. + /// + /// An for this object. public IEnumerator GetEnumerator () { - return new EntityEnumerator(_entities); + return new Enumerator(_entities); } #endregion #region IEnumerable Members + /// + /// Returns an enumerator that iterates through all entities. + /// + /// An for this object. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () { - return new EntityEnumerator(_entities); + return new Enumerator(_entities); } #endregion - public class EntityEnumerator : IEnumerator + /// + /// Enumerates the entities within an . + /// + private struct Enumerator : IEnumerator { private IEnumerator _enum; private EntityTyped _cur; - public EntityEnumerator (TagNodeList entities) + internal Enumerator (TagNodeList entities) { _enum = entities.GetEnumerator(); + _cur = null; } #region IEnumerator Members + /// + /// Gets the at the current position of the enumerator. + /// public EntityTyped Current { get @@ -176,17 +216,27 @@ namespace Substrate #region IDisposable Members + /// + /// Releases all resources used by the . + /// public void Dispose () { } #endregion #region IEnumerator Members + /// + /// Gets the at the current position of the enumerator. + /// object System.Collections.IEnumerator.Current { get { return Current; } } + /// + /// Advances the enumerator to the next in the . + /// + /// True if the enumerator was successfully advanced to the next position; false if the enumerator advanced past the end of the collection. public bool MoveNext () { if (!_enum.MoveNext()) { @@ -197,7 +247,10 @@ namespace Substrate return true; } - public void Reset () + /// + /// Sets the enumerator to its initial position, which is before the first in the collection. + /// + void System.Collections.IEnumerator.Reset () { _cur = null; _enum.Reset(); diff --git a/Substrate/SubstrateCS/Source/ItemInfo.cs b/Substrate/SubstrateCS/Source/ItemInfo.cs index bfc4e45..26c1cd3 100644 --- a/Substrate/SubstrateCS/Source/ItemInfo.cs +++ b/Substrate/SubstrateCS/Source/ItemInfo.cs @@ -118,10 +118,11 @@ namespace Substrate public class ItemInfo { - public class ItemCache + private static Random _rand = new Random(); + + private class CacheTableDict : ICacheTable { private Dictionary _cache; - private static Random _rand = new Random(); public T this[int index] { @@ -135,25 +136,24 @@ namespace Substrate } } - public ItemCache (Dictionary cache) + public CacheTableDict (Dictionary cache) { _cache = cache; } - - public T Random () - { - List list = new List(_cache.Values); - return list[_rand.Next(list.Count)]; - } } - private static Dictionary _itemTable; + private static readonly Dictionary _itemTable; private int _id = 0; private string _name = ""; private int _stack = 1; - public static ItemCache ItemTable; + private static readonly CacheTableDict _itemTableCache; + + public static ICacheTable ItemTable + { + get { return _itemTableCache; } + } public int ID { @@ -189,6 +189,11 @@ namespace Substrate return this; } + public static ItemInfo GetRandomItem () + { + List list = new List(_itemTable.Values); + return list[_rand.Next(list.Count)]; + } public static ItemInfo IronShovel; public static ItemInfo IronPickaxe; @@ -300,8 +305,7 @@ namespace Substrate static ItemInfo () { _itemTable = new Dictionary(); - - ItemTable = new ItemCache(_itemTable); + _itemTableCache = new CacheTableDict(_itemTable); IronShovel = new ItemInfo(256, "Iron Shovel"); IronPickaxe = new ItemInfo(257, "Iron Pickaxe"); diff --git a/Substrate/SubstrateCS/Source/Level.cs b/Substrate/SubstrateCS/Source/Level.cs index ad1bbe7..ddfa442 100644 --- a/Substrate/SubstrateCS/Source/Level.cs +++ b/Substrate/SubstrateCS/Source/Level.cs @@ -13,7 +13,7 @@ namespace Substrate { new SchemaNodeScaler("Time", TagType.TAG_LONG), new SchemaNodeScaler("LastPlayed", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), - new SchemaNodeCompound("Player", Player.PlayerSchema, SchemaOptions.OPTIONAL), + new SchemaNodeCompound("Player", Player.Schema, SchemaOptions.OPTIONAL), new SchemaNodeScaler("SpawnX", TagType.TAG_INT), new SchemaNodeScaler("SpawnY", TagType.TAG_INT), new SchemaNodeScaler("SpawnZ", TagType.TAG_INT), diff --git a/Substrate/SubstrateCS/Source/Nbt/NbtIOException.cs b/Substrate/SubstrateCS/Source/Nbt/NbtIOException.cs new file mode 100644 index 0000000..0074b75 --- /dev/null +++ b/Substrate/SubstrateCS/Source/Nbt/NbtIOException.cs @@ -0,0 +1,48 @@ +using System; +using System.Runtime.Serialization; + +namespace Substrate.Nbt +{ + /// + /// The exception that is thrown when errors occur during Nbt IO operations. + /// + /// In most cases, the property will contain more detailed information on the + /// error that occurred. + [Serializable] + public class NbtIOException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public NbtIOException () + : base() + { } + + /// + /// Initializes a new instance of the class with a custom error message. + /// + /// A custom error message. + public NbtIOException (string message) + : base(message) + { } + + /// + /// Initializes a new instance of the class with a custom error message and a reference to + /// an InnerException representing the original cause of the exception. + /// + /// A custom error message. + /// A reference to the original exception that caused the error. + public NbtIOException (string message, Exception innerException) + : base(message, innerException) + { } + + /// + /// Initializes a new instance of the class with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or destination. + protected NbtIOException (SerializationInfo info, StreamingContext context) + : base(info, context) + { } + } +} diff --git a/Substrate/SubstrateCS/Source/Player.cs b/Substrate/SubstrateCS/Source/Player.cs index 66e4d2d..58a8795 100644 --- a/Substrate/SubstrateCS/Source/Player.cs +++ b/Substrate/SubstrateCS/Source/Player.cs @@ -6,9 +6,14 @@ using Substrate.Nbt; namespace Substrate { + /// + /// Represents a Player from either single- or multi-player Minecraft. + /// + /// Unlike objects, objects do not need to be added to chunks. They + /// are stored individually or within level data. public class Player : Entity, INbtObject, ICopyable, IItemContainer { - public static readonly SchemaNodeCompound PlayerSchema = Entity.Schema.MergeInto(new SchemaNodeCompound("") + private static readonly SchemaNodeCompound _schema = Entity.Schema.MergeInto(new SchemaNodeCompound("") { new SchemaNodeScaler("AttackTime", TagType.TAG_SHORT), new SchemaNodeScaler("DeathTime", TagType.TAG_SHORT), @@ -42,72 +47,103 @@ namespace Substrate private ItemCollection _inventory; + /// + /// Gets or sets the number of ticks left in the player's "invincibility shield" after last struck. + /// public int AttackTime { get { return _attackTime; } set { _attackTime = (short)value; } } + /// + /// Gets or sets the number of ticks that the player has been dead for. + /// public int DeathTime { get { return _deathTime; } set { _deathTime = (short)value; } } + /// + /// Gets or sets the amount of the player's health. + /// public int Health { get { return _health; } set { _health = (short)value; } } + /// + /// Gets or sets the player's Hurt Time value. + /// public int HurtTime { get { return _hurtTime; } set { _hurtTime = (short)value; } } + /// + /// Gets or sets the dimension that the player is currently in. + /// public int Dimension { get { return _dimension; } set { _dimension = value; } } + /// + /// Gets or sets a value indicating whether the player is sleeping in a bed. + /// public bool IsSleeping { get { return _sleeping == 1; } set { _sleeping = (byte)(value ? 1 : 0); } } + /// + /// Gets or sets the player's Sleep Timer value. + /// public int SleepTimer { get { return _sleepTimer; } set { _sleepTimer = (short)value; } } - public int SpawnX + /// + /// Gets or sets the player's personal spawn point, set by sleeping in beds. + /// + public SpawnPoint Spawn { - get { return _spawnX ?? 0; } - set { _spawnX = value; } + get { return new SpawnPoint(_spawnX ?? 0, _spawnY ?? 0, _spawnZ ?? 0); } + set + { + _spawnX = value.X; + _spawnY = value.Y; + _spawnZ = value.Z; + } } - public int SpawnY + /// + /// Tests if the player currently has a personal spawn point. + /// + public bool HasSpawn { - get { return _spawnY ?? 0; } - set { _spawnY = value; } - } - - public int SpawnZ - { - get { return _spawnZ ?? 0; } - set { _spawnZ = value; } + get { return _spawnX != null && _spawnY != null && _spawnZ != null; } } + /// + /// Gets or sets the name of the world that the player is currently within. + /// public string World { get { return _world; } set { _world = value; } } + /// + /// Creates a new object with reasonable default values. + /// public Player () : base() { @@ -123,7 +159,11 @@ namespace Substrate Fire = -20; } - public Player (Player p) + /// + /// Creates a copy of a object. + /// + /// The to copy fields from. + protected Player (Player p) : base(p) { _attackTime = p._attackTime; @@ -141,9 +181,32 @@ namespace Substrate _inventory = p._inventory.Copy(); } + /// + /// Clears the player's personal spawn point. + /// + public void ClearSpawn () + { + _spawnX = null; + _spawnY = null; + _spawnZ = null; + } + #region INBTObject Members + /// + /// Gets a representing the schema of a Player. + /// + public static SchemaNodeCompound Schema + { + get { return _schema; } + } + + /// + /// Attempt to load a Player subtree into the without validation. + /// + /// The root node of a Player subtree. + /// The returns itself on success, or null if the tree was unparsable. public virtual new Player LoadTree (TagNode tree) { TagNodeCompound ctree = tree as TagNodeCompound; @@ -179,6 +242,11 @@ namespace Substrate return this; } + /// + /// Attempt to load a Player subtree into the with validation. + /// + /// The root node of a Player subtree. + /// The returns itself on success, or null if the tree failed validation. public virtual new Player LoadTreeSafe (TagNode tree) { if (!ValidateTree(tree)) { @@ -188,6 +256,10 @@ namespace Substrate return LoadTree(tree); } + /// + /// Builds a Player subtree from the current data. + /// + /// The root node of a Player subtree representing the current data. public virtual new TagNode BuildTree () { TagNodeCompound tree = base.BuildTree() as TagNodeCompound; @@ -215,9 +287,14 @@ namespace Substrate return tree; } + /// + /// Validate a Player subtree against a schema defintion. + /// + /// The root node of a Player subtree. + /// Status indicating whether the tree was valid against the internal schema. public virtual new bool ValidateTree (TagNode tree) { - return new NbtVerifier(tree, PlayerSchema).Verify(); + return new NbtVerifier(tree, _schema).Verify(); } #endregion @@ -225,6 +302,10 @@ namespace Substrate #region ICopyable Members + /// + /// Creates a deep-copy of the . + /// + /// A deep-copy of the . public virtual new Player Copy () { return new Player(this); @@ -235,6 +316,9 @@ namespace Substrate #region IItemContainer Members + /// + /// Gets access to an representing the player's equipment and inventory. + /// public ItemCollection Items { get { return _inventory; } diff --git a/Substrate/SubstrateCS/Source/PlayerIOException.cs b/Substrate/SubstrateCS/Source/PlayerIOException.cs new file mode 100644 index 0000000..eab4e22 --- /dev/null +++ b/Substrate/SubstrateCS/Source/PlayerIOException.cs @@ -0,0 +1,46 @@ +using System; +using System.Runtime.Serialization; + +namespace Substrate +{ + /// + /// The exception that is thrown when IO errors occur during high-level player management operations. + /// + [Serializable] + public class PlayerIOException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public PlayerIOException () + : base() + { } + + /// + /// Initializes a new instance of the class with a custom error message. + /// + /// A custom error message. + public PlayerIOException (string message) + : base(message) + { } + + /// + /// Initializes a new instance of the class with a custom error message and a reference to + /// an InnerException representing the original cause of the exception. + /// + /// A custom error message. + /// A reference to the original exception that caused the error. + public PlayerIOException (string message, Exception innerException) + : base(message, innerException) + { } + + /// + /// Initializes a new instance of the class with serialized data. + /// + /// The object that holds the serialized object data. + /// The contextual information about the source or destination. + protected PlayerIOException (SerializationInfo info, StreamingContext context) + : base(info, context) + { } + } +} diff --git a/Substrate/SubstrateCS/Source/PlayerManager.cs b/Substrate/SubstrateCS/Source/PlayerManager.cs index 69cad68..16fefe8 100644 --- a/Substrate/SubstrateCS/Source/PlayerManager.cs +++ b/Substrate/SubstrateCS/Source/PlayerManager.cs @@ -7,69 +7,133 @@ using Substrate.Nbt; namespace Substrate { - public class PlayerManager + /// + /// Functions to manage multiple entities and files in multiplayer settings. + /// + /// This manager is intended for player files stored in standard compressed NBT format. + public class PlayerManager : IPlayerManager { - protected string _playerPath; + private string _playerPath; + /// + /// Create a new for a given file path. + /// + /// Path to a directory containing player data files. public PlayerManager (string playerDir) { _playerPath = playerDir; } + /// + /// Gets a representing the backing NBT data stream. + /// + /// The name of the player to fetch. + /// A for the given player. protected PlayerFile GetPlayerFile (string name) { return new PlayerFile(_playerPath, name); } - protected NbtTree GetPlayerTree (string name) + /// + /// Gets a raw of data for the given player. + /// + /// The name of the player to fetch. + /// An containing the given player's raw data. + /// Thrown when the manager cannot read in an NBT data stream. + public NbtTree GetPlayerTree (string name) { PlayerFile pf = GetPlayerFile(name); Stream nbtstr = pf.GetDataInputStream(); if (nbtstr == null) { - return null; + throw new NbtIOException("Failed to initialize NBT data stream for input."); } return new NbtTree(nbtstr); } - protected bool SavePlayerTree (string name, NbtTree tree) + /// + /// Saves a raw representing a player to the given player's file. + /// + /// The name of the player to write data to. + /// The player's data as an . + /// Thrown when the manager cannot initialize an NBT data stream for output. + public void SetPlayerTree (string name, NbtTree tree) { PlayerFile pf = GetPlayerFile(name); Stream zipstr = pf.GetDataOutputStream(); if (zipstr == null) { - return false; + throw new NbtIOException("Failed to initialize NBT data stream for output."); } tree.WriteTo(zipstr); zipstr.Close(); - - return true; } + /// + /// Gets a object for the given player. + /// + /// The name of the player to fetch. + /// A object for the given player, or null if the player could not be found. + /// Thrown when the manager cannot read in a player that should exist. public Player GetPlayer (string name) { if (!PlayerExists(name)) { return null; } - return new Player().LoadTreeSafe(GetPlayerTree(name).Root); + try { + return new Player().LoadTreeSafe(GetPlayerTree(name).Root); + } + catch (Exception ex) { + PlayerIOException pex = new PlayerIOException("Could not load player", ex); + pex.Data["PlayerName"] = name; + throw pex; + } } - public bool SetPlayer (string name, Player player) + /// + /// Saves a object's data back to the given player's file. + /// + /// The name of the player to write back to. + /// The object containing data to write back. + /// Thrown when the manager cannot write out the player. + public void SetPlayer (string name, Player player) { - return SavePlayerTree(name, new NbtTree(player.BuildTree() as TagNodeCompound)); + try { + SetPlayerTree(name, new NbtTree(player.BuildTree() as TagNodeCompound)); + } + catch (Exception ex) { + PlayerIOException pex = new PlayerIOException("Could not save player", ex); + pex.Data["PlayerName"] = name; + throw pex; + } } + /// + /// Checks if data for a player with the given name exists. + /// + /// The name of the player to look up. + /// True if player data was found; false otherwise. public bool PlayerExists (string name) { return new PlayerFile(_playerPath, name).Exists(); } - public bool DeletePlayer (string name) + /// + /// Deletes a player with the given name from the underlying data store. + /// + /// The name of the player to delete. + /// Thrown when the manager cannot delete the player. + public void DeletePlayer (string name) { - new PlayerFile(_playerPath, name).Delete(); - - return true; + try { + new PlayerFile(_playerPath, name).Delete(); + } + catch (Exception ex) { + PlayerIOException pex = new PlayerIOException("Could not save player", ex); + pex.Data["PlayerName"] = name; + throw pex; + } } } } diff --git a/Substrate/SubstrateCS/Source/RegionManager.cs b/Substrate/SubstrateCS/Source/RegionManager.cs index 60c8bb3..b6aebbf 100644 --- a/Substrate/SubstrateCS/Source/RegionManager.cs +++ b/Substrate/SubstrateCS/Source/RegionManager.cs @@ -132,7 +132,7 @@ namespace Substrate public IEnumerator GetEnumerator () { - return new RegionEnumerator(this); + return new Enumerator(this); } #endregion @@ -141,26 +141,27 @@ namespace Substrate IEnumerator IEnumerable.GetEnumerator () { - return new RegionEnumerator(this); + return new Enumerator(this); } #endregion - public class RegionEnumerator : IEnumerator + private struct Enumerator : IEnumerator { - protected List _regions; + private List _regions; + private int _pos; - protected int _pos = -1; - - public RegionEnumerator (List regs) + public Enumerator (List regs) { _regions = regs; + _pos = -1; } - public RegionEnumerator (RegionManager rm) + public Enumerator (RegionManager rm) { _regions = new List(); + _pos = -1; if (!Directory.Exists(rm.GetRegionPath())) { throw new DirectoryNotFoundException(); diff --git a/Substrate/SubstrateCS/Source/SpawnPoint.cs b/Substrate/SubstrateCS/Source/SpawnPoint.cs new file mode 100644 index 0000000..92df87b --- /dev/null +++ b/Substrate/SubstrateCS/Source/SpawnPoint.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate +{ + /// + /// Represents the spawn point of a player or world. + /// + /// values are immutable. To change an existing spawn point, create a new instance with + /// the new coordinate(s). Since some spawn points are optional in Minecraft, this helps safegaurd against saving a partial + /// spawn point. + public struct SpawnPoint : IEquatable + { + private readonly int _x; + private readonly int _y; + private readonly int _z; + + /// + /// Gets the global X-coordinate of the spawn point (in blocks). + /// + public int X + { + get { return _x; } + } + + /// + /// Gets the global Y-coordinate of the spawn point (in blocks). + /// + public int Y + { + get { return _y; } + } + + /// + /// Gets the global Z-coordinate of the spawn point (in blocks). + /// + public int Z + { + get { return _z; } + } + + /// + /// Creates a new spawn point. + /// + /// The global X-coordinate of the spawn point. + /// The global Y-coordinate of the spawn point. + /// The global Z-coordinate of the spawn point. + public SpawnPoint (int x, int y, int z) + { + _x = x; + _y = y; + _z = z; + } + + /// + /// Checks if two objects are considered equal. + /// + /// A to compare against. + /// True if the two objects are equal; false otherwise. + public bool Equals (SpawnPoint spawn) + { + return this._x == spawn._x && this._y == spawn._y && this._z == spawn._z; + } + + /// + /// Checks if two objects are considered equal. + /// + /// An to compare against. + /// True if the two objects are equal; false otherwise. + public override bool Equals (Object o) + { + if (o is SpawnPoint) { + return this == (SpawnPoint)o; + } + else { + return false; + } + } + + /// + /// Returns the hash code for this instance. + /// + /// A hash code for this instance. + public override int GetHashCode () + { + int hash = 23; + hash = hash * 37 + _x; + hash = hash * 37 + _y; + hash = hash * 37 + _z; + return hash; + } + + /// + /// Checks if two objects are considered equal. + /// + /// The first in the comparison. + /// The second in the comparison. + /// True if the two objects are equal; false otherwise. + public static bool operator == (SpawnPoint k1, SpawnPoint k2) + { + return k1._x == k2._x && k1._y == k2._y && k1._z == k2._z; + } + + /// + /// Checks if two objects are considered unequal. + /// + /// The first in the comparison. + /// The second in the comparison. + /// True if the two objects are not equal; false otherwise. + public static bool operator != (SpawnPoint k1, SpawnPoint k2) + { + return k1._x != k2._x || k1._y != k2._y || k1._z != k2._z; + } + + /// + /// Returns a string representation of the . + /// + /// A string representing this . + public override string ToString () + { + return "(" + _x + ", " + _y + ", " + _z + ")"; + } + } +} diff --git a/Substrate/SubstrateCS/Substrate.csproj b/Substrate/SubstrateCS/Substrate.csproj index b3904cc..615d8e2 100644 --- a/Substrate/SubstrateCS/Substrate.csproj +++ b/Substrate/SubstrateCS/Substrate.csproj @@ -64,7 +64,9 @@ + + @@ -74,7 +76,14 @@ - + + Code + + + + + Code + @@ -96,6 +105,8 @@ + + @@ -142,13 +153,12 @@ - - + @@ -164,6 +174,7 @@ +