public void CheckSubDir(World world, SegmentCoords coords) { var subCoords = new SubdirectoryCoords(coords); string subDir = "d-" + subCoords.X.ToString("X") + "-" + subCoords.Y.ToString("X") + "-" + subCoords.Z.ToString("X"); string path = world.SegmentManager.SegmentPath + subDir; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } }
public World ConvertWorld(String mcDirectory) { String segmentDirectory = Path.Combine(FCEDirectory, "Segments"); if (!Directory.Exists(FCEDirectory)) { Directory.CreateDirectory(FCEDirectory); } if (!Directory.Exists(Path.Combine(FCEDirectory, segmentDirectory))) { Directory.CreateDirectory(segmentDirectory); } Boolean anvil = true; NbtWorld nbtWorld = AnvilWorld.Open(mcDirectory); String worldName = nbtWorld.Level.LevelName; IChunkManager chunkManager = nbtWorld.GetChunkManager(); try { // Try to test for mc world type // Don't know how this is supposed to work, but it presumably throws an exception // on a non-Anvil world. chunkManager.Count(); } catch { anvil = false; nbtWorld = BetaWorld.Open(mcDirectory); worldName = nbtWorld.Level.LevelName; chunkManager = nbtWorld.GetChunkManager(); } Int32 spawnChunkX = nbtWorld.Level.Spawn.X >> 4; Int32 spawnChunkZ = nbtWorld.Level.Spawn.Z >> 4; WorldSettings settings = new WorldSettings(); settings.Name = worldName; var fceWorld = World.Create(FCEDirectory, settings); var segmentManager = fceWorld.SegmentManager; _totalSegments = chunkManager.LongCount() * (anvil ? 16 : 8); _segmentsLeft = _totalSegments; StartSaveThread(fceWorld); foreach (ChunkRef chunk in chunkManager) { // If the save thread is too slow, wait until it has caught up before adding to it to prevent high ram usage while (_saveQueue.Count > 5000) { Thread.Sleep(500); } if (chunk.Blocks == null) { _segmentsLeft -= (anvil ? 16 : 8); continue; } Int32 spawnOffsetX = UseSpawnAsOrigin ? spawnChunkX - chunk.X : -chunk.X; Int32 spawnOffsetZ = UseSpawnAsOrigin ? spawnChunkZ - chunk.Z : -chunk.Z; // Minecraft has different x/y directions so we must reverse z so the world isn't mirrored var chunkCoords = new SegmentCoords(spawnOffsetX, 0, -spawnOffsetZ) + SegmentCoords.WorldCenter; for (Int32 i = 0; i < (anvil ? 16 : 8); i++) { SegmentCoords segCoords = chunkCoords + SegmentCoords.Above * i; var segment = new Segment(segmentManager, segCoords); var array = new Cube[16, 16, 16]; for (Byte x = 0; x < 16; x++) { for (Byte y = 0; y < 16; y++) { for (Byte z = 0; z < 16; z++) { // Minecraft has different x/y directions so we must reverse z so the world isn't mirrored AlphaBlock block = chunk.Blocks.GetBlock(15 - z, y + i * 16, x); UInt32 mcIdData = (UInt32)block.ID << 16 | (UInt16)block.Data; Cube cube; if (!_mcIdDataToFCECube.TryGetValue(mcIdData, out cube)) { cube = new Cube(1, 0, 0, 0); if (!UnknownBlocks.ContainsKey((UInt16)block.ID)) { UnknownBlocks.Add((UInt16)block.ID, block.Info.Name); } } array[z, y, x] = cube; } } } segment.CubeData = array; _segmentsLeft--; _saveQueue.Enqueue(segment); } // Pad the area above the converted world with 11 blank segments to prevent world gen from occuring // Possibly replace this in the future with simply shifting the world up for (Int32 i = (anvil ? 16 : 8); i < 27; i++) { var padding = new Segment(segmentManager, chunkCoords + SegmentCoords.Above * i); padding.CubeData = Segment.GetBlankSegment().CubeData; padding.IsEmpty = true; _saveQueue.Enqueue(padding); } } Task.WaitAll(_saveTask); return(fceWorld); }