forked from mirrors/NBTExplorer
Split out generic NBTFile loader, added support for player IO and a PlayerManager.
This commit is contained in:
parent
0860bae2bc
commit
382399c141
7 changed files with 290 additions and 60 deletions
|
@ -6,16 +6,15 @@ using Ionic.Zlib;
|
||||||
|
|
||||||
namespace Substrate
|
namespace Substrate
|
||||||
{
|
{
|
||||||
class ChunkFile
|
public class ChunkFile : NBTFile
|
||||||
{
|
{
|
||||||
private string _filename;
|
|
||||||
|
|
||||||
public ChunkFile (string path)
|
public ChunkFile (string path)
|
||||||
|
: base(path)
|
||||||
{
|
{
|
||||||
_filename = path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkFile (string path, int cx, int cz)
|
public ChunkFile (string path, int cx, int cz)
|
||||||
|
: base("")
|
||||||
{
|
{
|
||||||
string cx64 = Base64(cx);
|
string cx64 = Base64(cx);
|
||||||
string cz64 = Base64(cz);
|
string cz64 = Base64(cz);
|
||||||
|
@ -33,55 +32,5 @@ namespace Substrate
|
||||||
{
|
{
|
||||||
return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(val.ToString()));
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Substrate
|
||||||
{
|
{
|
||||||
using NBT;
|
using NBT;
|
||||||
|
|
||||||
class ChunkFileManager : IChunkContainer, IChunkCache
|
public class ChunkFileManager : IChunkContainer, IChunkCache
|
||||||
{
|
{
|
||||||
protected string _mapPath;
|
protected string _mapPath;
|
||||||
|
|
||||||
|
|
70
Substrate/SubstrateCS/Source/NBTFile.cs
Normal file
70
Substrate/SubstrateCS/Source/NBTFile.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ namespace Substrate
|
||||||
using NBT;
|
using NBT;
|
||||||
using Utility;
|
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("")
|
public static readonly NBTCompoundNode PlayerSchema = UTBaseSchema.MergeInto(new NBTCompoundNode("")
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,8 @@ namespace Substrate
|
||||||
new NBTScalerNode("SpawnZ", NBT_Type.TAG_INT, NBTOptions.OPTIONAL),
|
new NBTScalerNode("SpawnZ", NBT_Type.TAG_INT, NBTOptions.OPTIONAL),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private const int _CAPACITY = 105;
|
||||||
|
|
||||||
private int _dimension;
|
private int _dimension;
|
||||||
private byte _sleeping;
|
private byte _sleeping;
|
||||||
private short _sleepTimer;
|
private short _sleepTimer;
|
||||||
|
@ -28,19 +30,69 @@ namespace Substrate
|
||||||
private int? _spawnY;
|
private int? _spawnY;
|
||||||
private int? _spawnZ;
|
private int? _spawnZ;
|
||||||
|
|
||||||
private string? _world;
|
private string _world;
|
||||||
|
|
||||||
private ItemCollection _inventory;
|
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 ()
|
public Player ()
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
|
_inventory = new ItemCollection(_CAPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player (Player p)
|
public Player (Player p)
|
||||||
: base(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;
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +140,21 @@ namespace Substrate
|
||||||
public virtual new NBT_Value BuildTree ()
|
public virtual new NBT_Value BuildTree ()
|
||||||
{
|
{
|
||||||
NBT_Compound tree = base.BuildTree() as NBT_Compound;
|
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;
|
return tree;
|
||||||
}
|
}
|
||||||
|
@ -88,5 +175,15 @@ namespace Substrate
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region IItemContainer Members
|
||||||
|
|
||||||
|
public ItemCollection Items
|
||||||
|
{
|
||||||
|
get { return _inventory; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
23
Substrate/SubstrateCS/Source/PlayerFile.cs
Normal file
23
Substrate/SubstrateCS/Source/PlayerFile.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
75
Substrate/SubstrateCS/Source/PlayerManager.cs
Normal file
75
Substrate/SubstrateCS/Source/PlayerManager.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ namespace Substrate
|
||||||
protected RegionManager _regionMan;
|
protected RegionManager _regionMan;
|
||||||
protected ChunkManager _chunkMan;
|
protected ChunkManager _chunkMan;
|
||||||
protected BlockManager _blockMan;
|
protected BlockManager _blockMan;
|
||||||
|
protected PlayerManager _playerMan;
|
||||||
|
|
||||||
protected string _worldPath;
|
protected string _worldPath;
|
||||||
|
|
||||||
|
@ -17,9 +18,19 @@ namespace Substrate
|
||||||
{
|
{
|
||||||
_worldPath = world;
|
_worldPath = world;
|
||||||
|
|
||||||
_regionMan = new RegionManager(Path.Combine(world, "region"));
|
if (Directory.Exists(Path.Combine(world, "region"))) {
|
||||||
_chunkMan = new ChunkManager(_regionMan);
|
_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);
|
_blockMan = new BlockManager(_chunkMan);
|
||||||
|
|
||||||
|
if (Directory.Exists(Path.Combine(world, "players"))) {
|
||||||
|
_playerMan = new PlayerManager(Path.Combine(world, "players"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegionManager GetRegionManager ()
|
public RegionManager GetRegionManager ()
|
||||||
|
@ -36,5 +47,10 @@ namespace Substrate
|
||||||
{
|
{
|
||||||
return _blockMan;
|
return _blockMan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PlayerManager GetPlayerManager ()
|
||||||
|
{
|
||||||
|
return _playerMan;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue