Properly handling Tile Entity consistency for block modification. Added building default trees from NBT schema, JSON Serializer for trees, start of a dumping command for nbtoolkit, and untested Chunk File support for Alpha maps.

This commit is contained in:
Justin Aquadro 2011-04-03 20:59:21 +00:00
parent 895178d5d3
commit d89a892623
18 changed files with 663 additions and 77 deletions

View file

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NBToolkit
{
using Map;
using Map.NBT;
using System.IO;
class Dump : TKFilter
{
private ReplaceOptions opt;
public Dump (ReplaceOptions o)
{
opt = o;
}
public override void Run ()
{
World world = new World(opt.OPT_WORLD);
StreamWriter fstr = new StreamWriter("json.txt", false);
foreach (ChunkRef chunk in new FilteredChunkList(world.GetChunkManager(), opt.GetChunkFilter())) {
string s = JSONSerializer.Serialize(chunk.GetChunkRef().Tree.Root["Level"].ToNBTCompound()["TileEntities"]);
fstr.Write(s);
}
fstr.Close();
}
}
}

View file

@ -434,7 +434,7 @@ namespace NBToolkit.Map
Dispenser.SetTileEntity("Trap", TileEntity.TrapSchema);
NoteBlock.SetTileEntity("Music", TileEntity.MusicSchema);
MonsterSpawner.SetTileEntity("MonsterSpawner", TileEntity.MonsterSpawnerSchema);
MonsterSpawner.SetTileEntity("MonsterSpawner", TileEntity.MobSpawnerSchema);
Chest.SetTileEntity("Chest", TileEntity.ChestSchema);
Furnace.SetTileEntity("Furnace", TileEntity.FurnaceSchema);
BurningFurnace.SetTileEntity("Furnace", TileEntity.FurnaceSchema);

View file

@ -32,6 +32,11 @@ namespace NBToolkit.Map
get { return _cz; }
}
public NBT_Tree Tree
{
get { return _tree; }
}
public bool IsTerrainPopulated
{
get { return _tree.Root["Level"].ToNBTCompound()["TerrainPopulated"].ToNBTByte() == 1; }
@ -64,6 +69,17 @@ namespace NBToolkit.Map
_entities = level["Entities"] as NBT_List;
_tileEntities = level["TileEntities"] as NBT_List;
// List-type patch up
if (_entities.Count == 0) {
level["Entities"] = new NBT_List(NBT_Type.TAG_COMPOUND);
_entities = level["Entities"] as NBT_List;
}
if (_tileEntities.Count == 0) {
level["TileEntities"] = new NBT_List(NBT_Type.TAG_COMPOUND);
_tileEntities = level["TileEntities"] as NBT_List;
}
_cx = level["xPos"].ToNBTInt();
_cz = level["zPos"].ToNBTInt();
}
@ -201,9 +217,18 @@ namespace NBToolkit.Map
// Update tile entities
if (BlockInfo.SchemaTable[_blocks[index]] != null &&
BlockInfo.SchemaTable[_blocks[index]] != BlockInfo.SchemaTable[id]) {
ClearTileEntity(lx, ly, lz);
if (BlockInfo.SchemaTable[_blocks[index]] != BlockInfo.SchemaTable[id]) {
if (BlockInfo.SchemaTable[_blocks[index]] != null) {
ClearTileEntity(lx, ly, lz);
}
if (BlockInfo.SchemaTable[id] != null) {
TileEntity te = new TileEntity(BlockInfo.SchemaTable[id]);
te.X = BlockGlobalX(lx);
te.Y = BlockGlobalY(ly);
te.Z = BlockGlobalZ(lz);
_tileEntities.Add(te.Root);
}
}
// Update height map
@ -301,10 +326,14 @@ namespace NBToolkit.Map
public TileEntity GetTileEntity (int lx, int ly, int lz)
{
int x = BlockGlobalX(lx);
int y = BlockGlobalY(ly);
int z = BlockGlobalZ(lz);
foreach (NBT_Compound te in _tileEntities) {
if (te["x"].ToNBTInt().Data == lx &&
te["y"].ToNBTInt().Data == ly &&
te["z"].ToNBTInt().Data == lz) {
if (te["x"].ToNBTInt().Data == x &&
te["y"].ToNBTInt().Data == y &&
te["z"].ToNBTInt().Data == z) {
return new TileEntity(te);
}
}
@ -327,23 +356,18 @@ namespace NBToolkit.Map
ClearTileEntity(lx, ly, lz);
int x = BlockX(lx);
int y = BlockY(ly);
int z = BlockZ(lz);
if (!te.LocatedAt(x, y, z)) {
te = te.Copy();
te.Relocate(x, y, z);
}
te.X = BlockGlobalX(lx);
te.Y = BlockGlobalY(ly);
te.Z = BlockGlobalZ(lz);
_tileEntities.Add(te.Root);
return true;
}
public bool ClearTileEntity (int x, int y, int z)
public bool ClearTileEntity (int lx, int ly, int lz)
{
TileEntity te = GetTileEntity(x, y, z);
TileEntity te = GetTileEntity(lx, ly, lz);
if (te == null) {
return false;
}
@ -365,21 +389,6 @@ namespace NBToolkit.Map
}
}
protected int BlockX (int lx)
{
return _cx * BlockManager.CHUNK_XLEN + lx;
}
protected int BlockY (int ly)
{
return ly;
}
protected int BlockZ (int lz)
{
return _cz * BlockManager.CHUNK_ZLEN + lz;
}
#region ICopyable<Chunk> Members
public Chunk Copy ()

View file

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Ionic.Zlib;
namespace NBToolkit.Map
{
class ChunkFile
{
private string _filename;
public ChunkFile (string path)
{
_filename = path;
}
public ChunkFile (string path, int cx, int cz)
{
string cx64 = Base64(cx);
string cz64 = Base64(cz);
string file = "c." + cx64 + "." + cz64 + ".dat";
string dir1 = Base64(cx % 64);
string dir2 = Base64(cz % 64);
_filename = Path.Combine(path, dir1);
_filename = Path.Combine(_filename, dir2);
_filename = Path.Combine(_filename, file);
}
private string Base64 (int val)
{
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

@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace NBToolkit.Map
{
using NBT;
class ChunkFileManager : IChunkContainer, IChunkCache
{
protected string _mapPath;
protected Dictionary<ChunkKey, WeakReference> _cache;
protected Dictionary<ChunkKey, ChunkRef> _dirty;
public ChunkFileManager (string mapDir)
{
_mapPath = mapDir;
_cache = new Dictionary<ChunkKey, WeakReference>();
_dirty = new Dictionary<ChunkKey, ChunkRef>();
}
protected ChunkFile GetChunkFile (int cx, int cz)
{
return new ChunkFile(_mapPath, cx, cz);
}
protected NBT_Tree GetChunkTree (int cx, int cz)
{
ChunkFile cf = GetChunkFile(cx, cz);
Stream nbtstr = cf.GetChunkDataInputStream();
if (nbtstr == null) {
return null;
}
return new NBT_Tree(nbtstr);
}
protected bool SaveChunkTree (int cx, int cz, NBT_Tree tree)
{
ChunkFile cf = GetChunkFile(cx, cz);
Stream zipstr = cf.GetChunkDataOutputStream();
if (zipstr == null) {
return false;
}
tree.WriteTo(zipstr);
zipstr.Close();
return true;
}
protected Stream GetChunkOutStream (int cx, int cz)
{
return new ChunkFile(_mapPath, cx, cz).GetChunkDataOutputStream();
}
#region IChunkContainer Members
public int ChunkGlobalX (int cx)
{
return cx;
}
public int ChunkGlobalZ (int cz)
{
return cz;
}
public int ChunkLocalX (int cx)
{
return cx;
}
public int ChunkLocalZ (int cz)
{
return cz;
}
public Chunk GetChunk (int cx, int cz)
{
if (!ChunkExists(cx, cz)) {
return null;
}
return new Chunk(GetChunkTree(cx, cz));
}
public ChunkRef GetChunkRef (int cx, int cz)
{
ChunkKey k = new ChunkKey(cx, cz);
ChunkRef c = null;
WeakReference chunkref = null;
if (_cache.TryGetValue(k, out chunkref)) {
c = chunkref.Target as ChunkRef;
}
else {
_cache.Add(k, new WeakReference(null));
}
if (c != null) {
return c;
}
try {
c = new ChunkRef(this, this, cx, cz);
_cache[k].Target = c;
return c;
}
catch (MissingChunkException) {
return null;
}
}
public bool ChunkExists (int cx, int cz)
{
return new ChunkFile(_mapPath, cx, cz).Exists();
}
public bool DeleteChunk (int cx, int cz)
{
new ChunkFile(_mapPath, cx, cz).Delete();
ChunkKey k = new ChunkKey(cx, cz);
_cache.Remove(k);
_dirty.Remove(k);
return true;
}
public int Save ()
{
int saved = 0;
foreach (ChunkRef c in _dirty.Values) {
int cx = ChunkGlobalX(c.X);
int cz = ChunkGlobalZ(c.Z);
if (c.Save(GetChunkOutStream(cx, cz))) {
saved++;
}
}
_dirty.Clear();
return saved;
}
public bool SaveChunk (Chunk chunk)
{
return chunk.Save(GetChunkOutStream(ChunkGlobalX(chunk.X), ChunkGlobalZ(chunk.Z)));
}
#endregion
#region IChunkCache Members
public bool MarkChunkDirty (ChunkRef chunk)
{
int cx = chunk.X;
int cz = chunk.Z;
ChunkKey k = new ChunkKey(cx, cz);
if (!_dirty.ContainsKey(k)) {
_dirty.Add(k, GetChunkRef(cx, cz));
return true;
}
return false;
}
public bool MarkChunkClean (ChunkRef chunk)
{
int cx = chunk.X;
int cz = chunk.Z;
ChunkKey k = new ChunkKey(cx, cz);
if (_dirty.ContainsKey(k)) {
_dirty.Remove(k);
return true;
}
return false;
}
#endregion
}
}

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace NBToolkit.Map
{
@ -23,7 +24,7 @@ namespace NBToolkit.Map
public interface IChunkCache
{
bool MarkChunkDirty (ChunkRef chunk);
bool MarkChunkClean (int cx, int cz);
bool MarkChunkClean (ChunkRef chunk);
}
public interface IChunkContainer

View file

@ -93,15 +93,19 @@ namespace NBToolkit.Map
return true;
}
public bool MarkChunkClean (int cx, int cz)
public bool MarkChunkClean (ChunkRef chunk)
{
Region r = GetRegion(cx, cz);
Region r = GetRegion(chunk.X, chunk.Z);
if (r == null) {
return false;
}
RegionKey k = new RegionKey(r.X, r.Z);
return _dirty.Remove(k);
_dirty.Remove(k);
r.MarkChunkClean(chunk);
return true;
}
public int Save ()

View file

@ -0,0 +1,164 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NBToolkit.Map.NBT
{
class JSONSerializer
{
public static string Serialize (NBT_Value tag)
{
StringBuilder str = new StringBuilder();
if (tag.GetNBTType() == NBT_Type.TAG_COMPOUND) {
SerializeCompound(tag as NBT_Compound, str, 0);
}
else if (tag.GetNBTType() == NBT_Type.TAG_LIST) {
SerializeList(tag as NBT_List, str, 0);
}
else {
SerializeScaler(tag, str);
}
str.AppendLine();
return str.ToString();
}
private static void SerializeCompound (NBT_Compound tag, StringBuilder str, int level)
{
if (tag.Count == 0) {
str.Append("{ }");
return;
}
str.AppendLine();
AddLine(str, "{", level);
IEnumerator<KeyValuePair<string, NBT_Value>> en = tag.GetEnumerator();
bool first = true;
while (en.MoveNext()) {
if (!first) {
str.Append(",");
str.AppendLine();
}
KeyValuePair<string, NBT_Value> item = en.Current;
Add(str, "\"" + item.Key + "\": ", level + 1);
if (item.Value.GetNBTType() == NBT_Type.TAG_COMPOUND) {
SerializeCompound(item.Value as NBT_Compound, str, level + 1);
}
else if (item.Value.GetNBTType() == NBT_Type.TAG_LIST) {
SerializeList(item.Value as NBT_List, str, level + 1);
}
else {
SerializeScaler(item.Value, str);
}
first = false;
}
str.AppendLine();
Add(str, "}", level);
}
private static void SerializeList (NBT_List tag, StringBuilder str, int level)
{
if (tag.Count == 0) {
str.Append("[ ]");
return;
}
str.AppendLine();
AddLine(str, "[", level);
IEnumerator<NBT_Value> en = tag.GetEnumerator();
bool first = true;
while (en.MoveNext()) {
if (!first) {
str.Append(",");
}
NBT_Value item = en.Current;
if (item.GetNBTType() == NBT_Type.TAG_COMPOUND) {
SerializeCompound(item as NBT_Compound, str, level + 1);
}
else if (item.GetNBTType() == NBT_Type.TAG_LIST) {
SerializeList(item as NBT_List, str, level + 1);
}
else {
if (!first) {
str.AppendLine();
}
Indent(str, level + 1);
SerializeScaler(item, str);
}
first = false;
}
str.AppendLine();
Add(str, "]", level);
}
private static void SerializeScaler (NBT_Value tag, StringBuilder str)
{
NBT_Type type = tag.GetNBTType();
switch (tag.GetNBTType()) {
case NBT_Type.TAG_STRING:
str.Append("\"" + tag.ToNBTString().Data + "\"");
break;
case NBT_Type.TAG_BYTE:
str.Append(tag.ToNBTByte().Data);
break;
case NBT_Type.TAG_SHORT:
str.Append(tag.ToNBTShort().Data);
break;
case NBT_Type.TAG_INT:
str.Append(tag.ToNBTInt().Data);
break;
case NBT_Type.TAG_LONG:
str.Append(tag.ToNBTLong().Data);
break;
case NBT_Type.TAG_FLOAT:
str.Append(tag.ToNBTFloat().Data);
break;
case NBT_Type.TAG_DOUBLE:
str.Append(tag.ToNBTDouble().Data);
break;
case NBT_Type.TAG_BYTE_ARRAY:
str.Append("null");
break;
}
}
private static void AddLine (StringBuilder str, string line, int level)
{
Indent(str, level);
str.AppendLine(line);
}
private static void Add (StringBuilder str, string line, int level)
{
Indent(str, level);
str.Append(line);
}
private static void Indent (StringBuilder str, int count)
{
for (int i = 0; i < count; i++) {
str.Append("\t");
}
}
}
}

View file

@ -17,6 +17,11 @@ namespace NBToolkit.Map.NBT
{
_name = name;
}
public virtual NBT_Value BuildDefaultTree ()
{
return null;
}
}
public class NBTScalerNode : NBTSchemaNode
@ -33,11 +38,39 @@ namespace NBToolkit.Map.NBT
{
_type = type;
}
public override NBT_Value BuildDefaultTree ()
{
switch (_type) {
case NBT_Type.TAG_STRING:
return new NBT_String();
case NBT_Type.TAG_BYTE:
return new NBT_Byte();
case NBT_Type.TAG_SHORT:
return new NBT_Short();
case NBT_Type.TAG_INT:
return new NBT_Int();
case NBT_Type.TAG_LONG:
return new NBT_Long();
case NBT_Type.TAG_FLOAT:
return new NBT_Float();
case NBT_Type.TAG_DOUBLE:
return new NBT_Double();
}
return null;
}
}
public class NBTStringNode : NBTSchemaNode
{
private string _value;
private string _value = "";
private int _length;
public int Length
@ -61,6 +94,15 @@ namespace NBToolkit.Map.NBT
{
_length = length;
}
public override NBT_Value BuildDefaultTree ()
{
if (_value.Length > 0) {
return new NBT_String(_value);
}
return new NBT_String();
}
}
public class NBTArrayNode : NBTSchemaNode
@ -83,6 +125,11 @@ namespace NBToolkit.Map.NBT
{
_length = length;
}
public override NBT_Value BuildDefaultTree ()
{
return new NBT_ByteArray(new byte[_length]);
}
}
public class NBTListNode : NBTSchemaNode
@ -112,13 +159,6 @@ namespace NBToolkit.Map.NBT
_type = type;
}
public NBTListNode (string name, NBT_Type type, int length)
: base(name)
{
_type = type;
_length = length;
}
public NBTListNode (string name, NBT_Type type, NBTSchemaNode subschema)
: base(name)
{
@ -133,6 +173,20 @@ namespace NBToolkit.Map.NBT
_length = length;
_subschema = subschema;
}
public override NBT_Value BuildDefaultTree ()
{
if (_length == 0) {
return new NBT_List(_type);
}
NBT_List list = new NBT_List(_type);
for (int i = 0; i < _length; i++) {
list.Add(_subschema.BuildDefaultTree());
}
return list;
}
}
public class NBTCompoundNode : NBTSchemaNode, ICollection<NBTSchemaNode>
@ -213,12 +267,22 @@ namespace NBToolkit.Map.NBT
foreach (NBTSchemaNode node in _subnodes) {
NBTSchemaNode f = tree._subnodes.Find(n => n.Name == node.Name);
if (f != null) {
tree.Remove(f);
continue;
}
tree.Add(node);
}
return tree;
}
public override NBT_Value BuildDefaultTree ()
{
NBT_Compound list = new NBT_Compound();
foreach (NBTSchemaNode node in _subnodes) {
list[node.Name] = node.BuildDefaultTree();
}
return list;
}
}
}

View file

@ -319,7 +319,7 @@ namespace NBToolkit.Map.NBT {
public class NBT_String : NBT_Value
{
private string _data = null;
private string _data = "";
override public NBT_String ToNBTString () { return this; }
override public NBT_Type GetNBTType () { return NBT_Type.TAG_STRING; }

View file

@ -175,6 +175,11 @@ namespace NBToolkit.Map.NBT
return false;
}
// Patch up empty lists
//if (schema.Length == 0) {
// tag = new NBT_List(schema.Type);
//}
bool pass = true;
// If a subschema is set, test all items in list against it

View file

@ -215,22 +215,22 @@ namespace NBToolkit.Map
public int ChunkGlobalX (int cx)
{
return cx;
return _rx * ChunkManager.REGION_XLEN + cx;
}
public int ChunkGlobalZ (int cz)
{
return cz;
return _rz * ChunkManager.REGION_ZLEN + cz;
}
public int ChunkLocalX (int cx)
{
return cx & ChunkManager.REGION_XMASK;
return cx;
}
public int ChunkLocalZ (int cz)
{
return cz & ChunkManager.REGION_ZMASK;
return cz;
}
public Chunk GetChunk (int lcx, int lcz)
@ -277,8 +277,8 @@ namespace NBToolkit.Map
{
int saved = 0;
foreach (ChunkRef c in _dirty.Values) {
int lcx = ChunkLocalX(c.X);
int lcz = ChunkLocalZ(c.Z);
int lcx = c.LocalX;
int lcz = c.LocalZ;
if (!ChunkExists(lcx, lcz)) {
throw new MissingChunkException();
@ -316,8 +316,11 @@ namespace NBToolkit.Map
return false;
}
public bool MarkChunkClean (int lcx, int lcz)
public bool MarkChunkClean (ChunkRef chunk)
{
int lcx = chunk.LocalX;
int lcz = chunk.LocalZ;
ChunkKey k = new ChunkKey(lcx, lcz);
if (_dirty.ContainsKey(k)) {
_dirty.Remove(k);

View file

@ -16,6 +16,29 @@ namespace NBToolkit.Map
get { return _tree; }
}
public string ID
{
get { return _tree["id"].ToNBTString(); }
}
public int X
{
get { return _tree["x"].ToNBTInt(); }
set { _tree["x"] = new NBT_Int(value); }
}
public int Y
{
get { return _tree["y"].ToNBTInt(); }
set { _tree["y"] = new NBT_Int(value); }
}
public int Z
{
get { return _tree["z"].ToNBTInt(); }
set { _tree["z"] = new NBT_Int(value); }
}
public TileEntity (string id)
{
_tree = new NBT_Compound();
@ -30,6 +53,11 @@ namespace NBToolkit.Map
_tree = tree;
}
public TileEntity (NBTSchemaNode schema)
{
_tree = schema.BuildDefaultTree() as NBT_Compound;
}
public bool Verify ()
{
NBTVerifier v = new NBTVerifier(Root, BaseSchema);
@ -42,25 +70,11 @@ namespace NBToolkit.Map
return v.Verify();
}
public bool LocatedAt (int lx, int ly, int lz)
public bool LocatedAt (int x, int y, int z)
{
return _tree["x"].ToNBTInt().Data == lx &&
_tree["y"].ToNBTInt().Data == ly &&
_tree["z"].ToNBTInt().Data == lz;
}
public bool Relocate (int lx, int ly, int lz)
{
if (lx >= 0 && lx < BlockManager.CHUNK_XLEN &&
ly >= 0 && ly < BlockManager.CHUNK_YLEN &&
lz >= 0 && lz < BlockManager.CHUNK_ZLEN) {
_tree["x"].ToNBTInt().Data = lx;
_tree["y"].ToNBTInt().Data = ly;
_tree["z"].ToNBTInt().Data = lz;
return true;
}
return false;
return _tree["x"].ToNBTInt().Data == x &&
_tree["y"].ToNBTInt().Data == y &&
_tree["z"].ToNBTInt().Data == z;
}
#region Predefined Schemas
@ -98,9 +112,9 @@ namespace NBToolkit.Map
new NBTScalerNode("Text4", NBT_Type.TAG_STRING),
});
public static readonly NBTCompoundNode MonsterSpawnerSchema = BaseSchema.MergeInto(new NBTCompoundNode("")
public static readonly NBTCompoundNode MobSpawnerSchema = BaseSchema.MergeInto(new NBTCompoundNode("")
{
new NBTStringNode("id", "MonsterSpawner"),
new NBTStringNode("id", "MobSpawner"),
new NBTScalerNode("EntityId", NBT_Type.TAG_STRING),
new NBTScalerNode("Delay", NBT_Type.TAG_SHORT),
});

View file

@ -57,12 +57,17 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Dump.cs" />
<Compile Include="Map\Block.cs" />
<Compile Include="Map\BlockInfo.cs" />
<Compile Include="Map\BlockInterface.cs" />
<Compile Include="Map\BlockKey.cs" />
<Compile Include="Map\BlockManager.cs" />
<Compile Include="Map\BlockRef.cs" />
<Compile Include="Map\Chunk.cs" />
<Compile Include="Map\ChunkFile.cs" />
<Compile Include="Map\ChunkFileManager.cs" />
<Compile Include="Map\ChunkInterface.cs" />
<Compile Include="Map\ChunkRef.cs" />
<Compile Include="Map\ChunkEnumerator.cs" />
<Compile Include="ChunkFilter.cs" />
@ -71,6 +76,7 @@
<Compile Include="Map\ChunkVerifier.cs" />
<Compile Include="FilteredChunkEnumerator.cs" />
<Compile Include="GenOres.cs" />
<Compile Include="Map\NBT\JSONSerializer.cs" />
<Compile Include="Map\TileEntity.cs" />
<Compile Include="Map\Utility\Interface.cs" />
<Compile Include="MathHelper.cs" />

View file

@ -1,9 +1,9 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<StartArguments>oregen -w "F:\Minecraft\tps - Copy" -b 15 --chunkinclude=35 -vv --MaxDepth=75 --MinDepth=67</StartArguments>
<StartArguments>replace -w "F:\Minecraft\tps - Copy" -b 61 -a 18 -vv</StartArguments>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<StartArguments>oregen -w "F:\Minecraft\tps - Copy" -b 15 --chunkinclude=35 -vv --MaxDepth=75 --MinDepth=67</StartArguments>
<StartArguments>replace -w "F:\Minecraft\tps - Copy" -b 61 -a 18 -vv</StartArguments>
</PropertyGroup>
<PropertyGroup>
<PublishUrlHistory>publish\</PublishUrlHistory>

View file

@ -199,7 +199,7 @@ namespace NBToolkit
ApplyChunk(world, chunk);
world.GetChunkManager().SaveDirtyChunks();
world.GetChunkManager().Save();
}
Console.WriteLine("Affected Chunks: " + affectedChunks);

View file

@ -36,6 +36,12 @@ namespace NBToolkit
options.SetDefaults();
filter.Run();
}
else if (args[0] == "dump") {
ReplaceOptions options = new ReplaceOptions(args);
Dump filter = new Dump(options);
options.SetDefaults();
filter.Run();
}
else if (args[0] == "help") {
if (args.Length < 2) {
args = new string[2] { "help", "help" };

View file

@ -157,7 +157,8 @@ namespace NBToolkit
affectedChunks++;
ApplyChunk(world, chunk);
chunk.Save();
world.GetChunkManager().Save();
}
Console.WriteLine("Affected Chunks: " + affectedChunks);