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