From 382399c141b0e402a79b142b5828d7775b763a8e Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Thu, 7 Apr 2011 07:03:54 +0000 Subject: [PATCH] Split out generic NBTFile loader, added support for player IO and a PlayerManager. --- Substrate/SubstrateCS/Source/ChunkFile.cs | 57 +--------- .../SubstrateCS/Source/ChunkFileManager.cs | 2 +- Substrate/SubstrateCS/Source/NBTFile.cs | 70 ++++++++++++ Substrate/SubstrateCS/Source/Player.cs | 103 +++++++++++++++++- Substrate/SubstrateCS/Source/PlayerFile.cs | 23 ++++ Substrate/SubstrateCS/Source/PlayerManager.cs | 75 +++++++++++++ Substrate/SubstrateCS/Source/World.cs | 20 +++- 7 files changed, 290 insertions(+), 60 deletions(-) create mode 100644 Substrate/SubstrateCS/Source/NBTFile.cs create mode 100644 Substrate/SubstrateCS/Source/PlayerFile.cs create mode 100644 Substrate/SubstrateCS/Source/PlayerManager.cs diff --git a/Substrate/SubstrateCS/Source/ChunkFile.cs b/Substrate/SubstrateCS/Source/ChunkFile.cs index d91a5e8..5695a2e 100644 --- a/Substrate/SubstrateCS/Source/ChunkFile.cs +++ b/Substrate/SubstrateCS/Source/ChunkFile.cs @@ -6,16 +6,15 @@ using Ionic.Zlib; namespace Substrate { - class ChunkFile + public class ChunkFile : NBTFile { - private string _filename; - public ChunkFile (string path) + : base(path) { - _filename = path; } public ChunkFile (string path, int cx, int cz) + : base("") { string cx64 = Base64(cx); string cz64 = Base64(cz); @@ -33,55 +32,5 @@ namespace Substrate { return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(val.ToString())); } - - public bool Exists () - { - return File.Exists(_filename); - } - - public bool Delete () - { - File.Delete(_filename); - return true; - } - - public Stream GetChunkDataInputStream () - { - FileStream fstr = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - - long length = fstr.Seek(0, SeekOrigin.End); - fstr.Seek(0, SeekOrigin.Begin); - - byte[] data = new byte[length]; - fstr.Read(data, 0, data.Length); - - fstr.Close(); - - return new GZipStream(new MemoryStream(data), CompressionMode.Decompress); - } - - public Stream GetChunkDataOutputStream () - { - return new ZlibStream(new ChunkBuffer(this), CompressionMode.Compress); - } - - class ChunkBuffer : MemoryStream - { - private ChunkFile region; - - public ChunkBuffer (ChunkFile c) - : base(8096) - { - this.region = c; - } - - public override void Close () - { - FileStream fstr = new FileStream(region._filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); - fstr.Write(this.GetBuffer(), 0, (int)this.Length); - fstr.Close(); - } - } - } } diff --git a/Substrate/SubstrateCS/Source/ChunkFileManager.cs b/Substrate/SubstrateCS/Source/ChunkFileManager.cs index 8b28689..7e9cfa4 100644 --- a/Substrate/SubstrateCS/Source/ChunkFileManager.cs +++ b/Substrate/SubstrateCS/Source/ChunkFileManager.cs @@ -7,7 +7,7 @@ namespace Substrate { using NBT; - class ChunkFileManager : IChunkContainer, IChunkCache + public class ChunkFileManager : IChunkContainer, IChunkCache { protected string _mapPath; diff --git a/Substrate/SubstrateCS/Source/NBTFile.cs b/Substrate/SubstrateCS/Source/NBTFile.cs new file mode 100644 index 0000000..3bc5a28 --- /dev/null +++ b/Substrate/SubstrateCS/Source/NBTFile.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Ionic.Zlib; + +namespace Substrate +{ + using NBT; + + public class NBTFile + { + protected string _filename; + + public NBTFile (string path) + { + _filename = path; + } + + public bool Exists () + { + return File.Exists(_filename); + } + + public bool Delete () + { + File.Delete(_filename); + return true; + } + + public Stream GetChunkDataInputStream () + { + FileStream fstr = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + + long length = fstr.Seek(0, SeekOrigin.End); + fstr.Seek(0, SeekOrigin.Begin); + + byte[] data = new byte[length]; + fstr.Read(data, 0, data.Length); + + fstr.Close(); + + return new GZipStream(new MemoryStream(data), CompressionMode.Decompress); + } + + public Stream GetChunkDataOutputStream () + { + return new ZlibStream(new NBTBuffer(this), CompressionMode.Compress); + } + + class NBTBuffer : MemoryStream + { + private NBTFile file; + + public NBTBuffer (NBTFile c) + : base(8096) + { + this.file = c; + } + + 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(); + } + } + + } +} diff --git a/Substrate/SubstrateCS/Source/Player.cs b/Substrate/SubstrateCS/Source/Player.cs index 027dda3..c19b856 100644 --- a/Substrate/SubstrateCS/Source/Player.cs +++ b/Substrate/SubstrateCS/Source/Player.cs @@ -7,7 +7,7 @@ namespace Substrate using NBT; using Utility; - public class Player : UntypedEntity, INBTObject, ICopyable + public class Player : UntypedEntity, INBTObject, ICopyable, IItemContainer { public static readonly NBTCompoundNode PlayerSchema = UTBaseSchema.MergeInto(new NBTCompoundNode("") { @@ -21,6 +21,8 @@ namespace Substrate new NBTScalerNode("SpawnZ", NBT_Type.TAG_INT, NBTOptions.OPTIONAL), }); + private const int _CAPACITY = 105; + private int _dimension; private byte _sleeping; private short _sleepTimer; @@ -28,19 +30,69 @@ namespace Substrate private int? _spawnY; private int? _spawnZ; - private string? _world; + private string _world; private ItemCollection _inventory; + public int Dimension + { + get { return _dimension; } + set { _dimension = value; } + } + + public bool IsSleeping + { + get { return _sleeping == 1; } + set { _sleeping = (byte)(value ? 1 : 0); } + } + + public int SleepTimer + { + get { return _sleepTimer; } + set { _sleepTimer = (short)value; } + } + + public int SpawnX + { + get { return _spawnX ?? 0; } + set { _spawnX = value; } + } + + public int SpawnY + { + get { return _spawnY ?? 0; } + set { _spawnY = value; } + } + + public int SpawnZ + { + get { return _spawnZ ?? 0; } + set { _spawnZ = value; } + } + + public string World + { + get { return _world; } + set { _world = value; } + } + public Player () : base() { + _inventory = new ItemCollection(_CAPACITY); } public Player (Player p) : base(p) { - + _dimension = p._dimension; + _sleeping = p._sleeping; + _sleepTimer = p._sleepTimer; + _spawnX = p._spawnX; + _spawnY = p._spawnY; + _spawnZ = p._spawnZ; + _world = p._world; + _inventory = p._inventory.Copy(); } @@ -53,6 +105,26 @@ namespace Substrate return null; } + _dimension = ctree["Dimension"].ToNBTInt(); + _sleeping = ctree["Sleeping"].ToNBTByte(); + _sleepTimer = ctree["SleepTimer"].ToNBTShort(); + + if (ctree.ContainsKey("SpawnX")) { + _spawnX = ctree["SpawnX"].ToNBTInt(); + } + if (ctree.ContainsKey("SpawnY")) { + _spawnY = ctree["SpawnY"].ToNBTInt(); + } + if (ctree.ContainsKey("SpawnZ")) { + _spawnZ = ctree["SpawnZ"].ToNBTInt(); + } + + if (ctree.ContainsKey("World")) { + _world = ctree["World"].ToNBTString(); + } + + _inventory.LoadTree(ctree["Inventory"].ToNBTList()); + return this; } @@ -68,6 +140,21 @@ namespace Substrate public virtual new NBT_Value BuildTree () { NBT_Compound tree = base.BuildTree() as NBT_Compound; + tree["Dimension"] = new NBT_Int(_dimension); + tree["Sleeping"] = new NBT_Byte(_sleeping); + tree["SleepTimer"] = new NBT_Short(_sleepTimer); + + if (_spawnX != null && _spawnY != null && _spawnZ != null) { + tree["SpawnX"] = new NBT_Int(_spawnX ?? 0); + tree["SpawnY"] = new NBT_Int(_spawnY ?? 0); + tree["SpawnZ"] = new NBT_Int(_spawnZ ?? 0); + } + + if (_world != null) { + tree["World"] = new NBT_String(_world); + } + + tree["Inventory"] = _inventory.BuildTree(); return tree; } @@ -88,5 +175,15 @@ namespace Substrate } #endregion + + + #region IItemContainer Members + + public ItemCollection Items + { + get { return _inventory; } + } + + #endregion } } \ No newline at end of file diff --git a/Substrate/SubstrateCS/Source/PlayerFile.cs b/Substrate/SubstrateCS/Source/PlayerFile.cs new file mode 100644 index 0000000..ae86c91 --- /dev/null +++ b/Substrate/SubstrateCS/Source/PlayerFile.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Ionic.Zlib; + +namespace Substrate +{ + public class PlayerFile : NBTFile + { + public PlayerFile (string path) + : base(path) + { + } + + public PlayerFile (string path, string name) + : base("") + { + string file = name + ".dat"; + _filename = Path.Combine(path, file); + } + } +} diff --git a/Substrate/SubstrateCS/Source/PlayerManager.cs b/Substrate/SubstrateCS/Source/PlayerManager.cs new file mode 100644 index 0000000..2a1d447 --- /dev/null +++ b/Substrate/SubstrateCS/Source/PlayerManager.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Substrate +{ + using NBT; + + public class PlayerManager + { + protected string _playerPath; + + public PlayerManager (string playerDir) + { + _playerPath = playerDir; + } + + protected PlayerFile GetPlayerFile (string name) + { + return new PlayerFile(_playerPath, name); + } + + protected NBT_Tree GetPlayerTree (string name) + { + PlayerFile pf = GetPlayerFile(name); + Stream nbtstr = pf.GetChunkDataInputStream(); + if (nbtstr == null) { + return null; + } + + return new NBT_Tree(nbtstr); + } + + protected bool SavePlayerTree (string name, NBT_Tree tree) + { + PlayerFile pf = GetPlayerFile(name); + Stream zipstr = pf.GetChunkDataOutputStream(); + if (zipstr == null) { + return false; + } + + tree.WriteTo(zipstr); + zipstr.Close(); + + return true; + } + + public Player GetPlayer (string name) + { + if (!PlayerExists(name)) { + return null; + } + + return new Player().LoadTreeSafe(GetPlayerTree(name).Root); + } + + public bool SetPlayer (string name, Player player) + { + return SavePlayerTree(name, new NBT_Tree(player.BuildTree() as NBT_Compound)); + } + + public bool PlayerExists (string name) + { + return new PlayerFile(_playerPath, name).Exists(); + } + + public bool DeletePlayer (string name) + { + new PlayerFile(_playerPath, name).Delete(); + + return true; + } + } +} diff --git a/Substrate/SubstrateCS/Source/World.cs b/Substrate/SubstrateCS/Source/World.cs index 79c21f7..9cc9c81 100644 --- a/Substrate/SubstrateCS/Source/World.cs +++ b/Substrate/SubstrateCS/Source/World.cs @@ -10,6 +10,7 @@ namespace Substrate protected RegionManager _regionMan; protected ChunkManager _chunkMan; protected BlockManager _blockMan; + protected PlayerManager _playerMan; protected string _worldPath; @@ -17,9 +18,19 @@ namespace Substrate { _worldPath = world; - _regionMan = new RegionManager(Path.Combine(world, "region")); - _chunkMan = new ChunkManager(_regionMan); + if (Directory.Exists(Path.Combine(world, "region"))) { + _regionMan = new RegionManager(Path.Combine(world, "region")); + _chunkMan = new ChunkManager(_regionMan); + } + else if (Directory.Exists(Path.Combine(world, "0"))) { + //_chunkMan = new ChunkFileManager(world); + } + _blockMan = new BlockManager(_chunkMan); + + if (Directory.Exists(Path.Combine(world, "players"))) { + _playerMan = new PlayerManager(Path.Combine(world, "players")); + } } public RegionManager GetRegionManager () @@ -36,5 +47,10 @@ namespace Substrate { return _blockMan; } + + public PlayerManager GetPlayerManager () + { + return _playerMan; + } } }