diff --git a/Substrate/SubstrateCS/Examples/Convert/Convert.csproj b/Substrate/SubstrateCS/Examples/Convert/Convert.csproj
new file mode 100644
index 0000000..b356819
--- /dev/null
+++ b/Substrate/SubstrateCS/Examples/Convert/Convert.csproj
@@ -0,0 +1,56 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}
+ Exe
+ Properties
+ Example
+ Convert
+ v4.0
+ 512
+
+
+
+
+ 3.5
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\bin\Release\Substrate.dll
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Substrate/SubstrateCS/Examples/Convert/Program.cs b/Substrate/SubstrateCS/Examples/Convert/Program.cs
new file mode 100644
index 0000000..880a0bf
--- /dev/null
+++ b/Substrate/SubstrateCS/Examples/Convert/Program.cs
@@ -0,0 +1,57 @@
+using System;
+using Substrate;
+using Substrate.NBT;
+
+// This example will convert worlds between alpha and beta format.
+// This will convert chunks to and from region format, and copy level.dat
+// Other data, like players and other dims, will not be handled.
+
+namespace Convert
+{
+ class Program
+ {
+ static void Main (string[] args)
+ {
+ if (args.Length != 3) {
+ Console.WriteLine("Usage: Convert ");
+ return;
+ }
+
+ string src = args[0];
+ string dst = args[1];
+ string srctype = args[2];
+
+ // Open source and destrination worlds depending on conversion type
+ INBTWorld srcWorld;
+ INBTWorld dstWorld;
+ if (srctype == "a") {
+ srcWorld = AlphaWorld.Open(src);
+ dstWorld = BetaWorld.Create(dst);
+ }
+ else {
+ srcWorld = BetaWorld.Open(src);
+ dstWorld = AlphaWorld.Create(dst);
+ }
+
+ // Grab chunk managers to copy chunks
+ IChunkManager cmsrc = srcWorld.GetChunkManager();
+ IChunkManager cmdst = dstWorld.GetChunkManager();
+
+ // Copy each chunk from source to dest
+ foreach (ChunkRef chunk in cmsrc) {
+ cmdst.SetChunk(chunk.X, chunk.Z, chunk.GetChunkRef());
+ }
+
+ // Copy level data from source to dest
+ dstWorld.Level.LoadTreeSafe(srcWorld.Level.BuildTree());
+
+ // If we're creating an alpha world, get rid of the version field
+ if (srctype == "b") {
+ dstWorld.Level.Version = 0;
+ }
+
+ // Save level.dat
+ dstWorld.Level.Save();
+ }
+ }
+}
diff --git a/Substrate/SubstrateCS/Examples/Convert/Properties/AssemblyInfo.cs b/Substrate/SubstrateCS/Examples/Convert/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d56796a
--- /dev/null
+++ b/Substrate/SubstrateCS/Examples/Convert/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Example")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Example")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("18bbf372-f1a7-41d3-b43f-f9d04cdf41eb")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Substrate/SubstrateCS/Source/ChunkFile.cs b/Substrate/SubstrateCS/Source/ChunkFile.cs
index 07dd937..a599091 100644
--- a/Substrate/SubstrateCS/Source/ChunkFile.cs
+++ b/Substrate/SubstrateCS/Source/ChunkFile.cs
@@ -33,7 +33,15 @@ namespace Substrate
string dir2 = Base36.Encode(cz % 64);
_filename = Path.Combine(path, dir1);
+ if (!Directory.Exists(_filename)) {
+ Directory.CreateDirectory(_filename);
+ }
+
_filename = Path.Combine(_filename, dir2);
+ if (!Directory.Exists(_filename)) {
+ Directory.CreateDirectory(_filename);
+ }
+
_filename = Path.Combine(_filename, file);
}
}
diff --git a/Substrate/SubstrateCS/Source/ChunkFileManager.cs b/Substrate/SubstrateCS/Source/ChunkFileManager.cs
index ca8dab4..16e6a6f 100644
--- a/Substrate/SubstrateCS/Source/ChunkFileManager.cs
+++ b/Substrate/SubstrateCS/Source/ChunkFileManager.cs
@@ -144,6 +144,19 @@ namespace Substrate
return true;
}
+ public ChunkRef SetChunk (int cx, int cz, Chunk chunk)
+ {
+ DeleteChunk(cx, cz);
+ chunk.SetLocation(cx, cz);
+ chunk.Save(GetChunkOutStream(cx, cz));
+
+ ChunkRef cr = ChunkRef.Create(this, cx, cz);
+ ChunkKey k = new ChunkKey(cx, cz);
+ _cache[k] = cr;
+
+ return cr;
+ }
+
public int Save ()
{
foreach (KeyValuePair e in _cache) {
diff --git a/Substrate/SubstrateCS/Source/ChunkInterface.cs b/Substrate/SubstrateCS/Source/ChunkInterface.cs
index 8a26dcd..6eaaa8e 100644
--- a/Substrate/SubstrateCS/Source/ChunkInterface.cs
+++ b/Substrate/SubstrateCS/Source/ChunkInterface.cs
@@ -54,6 +54,8 @@ namespace Substrate
ChunkRef GetChunkRef (int cx, int cz);
ChunkRef CreateChunk (int cx, int cz);
+ ChunkRef SetChunk (int cx, int cz, Chunk chunk);
+
bool ChunkExists (int cx, int cz);
bool DeleteChunk (int cx, int cz);
diff --git a/Substrate/SubstrateCS/Source/ChunkManager.cs b/Substrate/SubstrateCS/Source/ChunkManager.cs
index dc9cd44..6a16316 100644
--- a/Substrate/SubstrateCS/Source/ChunkManager.cs
+++ b/Substrate/SubstrateCS/Source/ChunkManager.cs
@@ -123,6 +123,21 @@ namespace Substrate
return dst_r.GetChunkRef(dst_cx & REGION_XMASK, dst_cz & REGION_ZMASK);
}
+ public ChunkRef SetChunk (int cx, int cz, Chunk chunk)
+ {
+ Region r = GetRegion(cx, cz);
+ if (r == null) {
+ int rx = cx >> REGION_XLOG;
+ int rz = cz >> REGION_ZLOG;
+ r = _regionMan.CreateRegion(rx, rz);
+ }
+
+ chunk.SetLocation(cx, cz);
+ r.SaveChunk(chunk);
+
+ return r.GetChunkRef(cx & REGION_XMASK, cz & REGION_ZMASK);
+ }
+
public int Save ()
{
_cache.SyncDirty();
diff --git a/Substrate/SubstrateCS/Source/ChunkRef.cs b/Substrate/SubstrateCS/Source/ChunkRef.cs
index 8149375..0c6511f 100644
--- a/Substrate/SubstrateCS/Source/ChunkRef.cs
+++ b/Substrate/SubstrateCS/Source/ChunkRef.cs
@@ -146,7 +146,7 @@ namespace Substrate
public void SetChunkRef (Chunk chunk)
{
_chunk = chunk;
- _chunk.SetLocation(_cx, _cz);
+ _chunk.SetLocation(X, Z);
_dirty = true;
}
diff --git a/Substrate/SubstrateCS/Source/Level.cs b/Substrate/SubstrateCS/Source/Level.cs
index d987927..09ff730 100644
--- a/Substrate/SubstrateCS/Source/Level.cs
+++ b/Substrate/SubstrateCS/Source/Level.cs
@@ -105,6 +105,7 @@ namespace Substrate
public int Version
{
get { return _version ?? 0; }
+ set { _version = value; }
}
public string LevelName
@@ -221,6 +222,12 @@ namespace Substrate
return null;
}
+ _version = null;
+ _raining = null;
+ _rainTime = null;
+ _thundering = null;
+ _thunderTime = null;
+
TagCompound ctree = dtree["Data"].ToTagCompound();
_time = ctree["Time"].ToTagLong();
@@ -285,7 +292,7 @@ namespace Substrate
data["SizeOnDisk"] = new TagLong(_sizeOnDisk);
data["RandomSeed"] = new TagLong(_randomSeed);
- if (_version != null) {
+ if (_version != null && _version != 0) {
data["version"] = new TagInt(_version ?? 0);
}
diff --git a/Substrate/SubstrateCS/Source/Region.cs b/Substrate/SubstrateCS/Source/Region.cs
index f101ac1..12ec2e7 100644
--- a/Substrate/SubstrateCS/Source/Region.cs
+++ b/Substrate/SubstrateCS/Source/Region.cs
@@ -338,6 +338,27 @@ namespace Substrate
return true;
}
+ public ChunkRef SetChunk (int lcx, int lcz, Chunk chunk)
+ {
+ if (!LocalBoundsCheck(lcx, lcz)) {
+ Region alt = GetForeignRegion(lcx, lcz);
+ return (alt == null) ? null : alt.CreateChunk(ForeignX(lcx), ForeignZ(lcz));
+ }
+
+ DeleteChunk(lcx, lcz);
+
+ int cx = lcx + _rx * ChunkManager.REGION_XLEN;
+ int cz = lcz + _rz * ChunkManager.REGION_ZLEN;
+
+ chunk.SetLocation(cx, cz);
+ chunk.Save(GetChunkOutStream(lcx, lcz));
+
+ ChunkRef cr = ChunkRef.Create(this, lcx, lcz);
+ _cache.Insert(cr);
+
+ return cr;
+ }
+
public int Save ()
{
_cache.SyncDirty();
@@ -362,7 +383,8 @@ namespace Substrate
public bool SaveChunk (Chunk chunk)
{
- return chunk.Save(GetChunkOutStream(ChunkLocalX(chunk.X), ChunkLocalZ(chunk.Z)));
+ Console.WriteLine("Region[{0}, {1}].Save({2}, {3})", _rx, _rz, ForeignX(chunk.X),ForeignZ(chunk.Z));
+ return chunk.Save(GetChunkOutStream(ForeignX(chunk.X), ForeignZ(chunk.Z)));
}
#endregion