Split out generic NBTFile loader, added support for player IO and a PlayerManager.

This commit is contained in:
Justin Aquadro 2011-04-07 07:03:54 +00:00
parent 0860bae2bc
commit 382399c141
7 changed files with 290 additions and 60 deletions

View file

@ -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();
}
}
}
}

View file

@ -7,7 +7,7 @@ namespace Substrate
{
using NBT;
class ChunkFileManager : IChunkContainer, IChunkCache
public class ChunkFileManager : IChunkContainer, IChunkCache
{
protected string _mapPath;

View file

@ -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();
}
}
}
}

View file

@ -7,7 +7,7 @@ namespace Substrate
using NBT;
using Utility;
public class Player : UntypedEntity, INBTObject<Player>, ICopyable<Player>
public class Player : UntypedEntity, INBTObject<Player>, ICopyable<Player>, 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
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}