public void Read(Map map, int x, int y) { var index = (ushort)(64 * x + y); var offset = Helper.SearchOffset(fileData, streamReader.BaseStream.Position, new byte[] { 0x4B, 0x4E, 0x43, 0x4D }); while (offset != 0) { streamReader.BaseStream.Position = offset + 12; var chunk = new MapChunk(); chunk.IndexX = (byte)streamReader.ReadUInt32(); chunk.IndexY = (byte)streamReader.ReadUInt32(); streamReader.BaseStream.Position += 40; chunk.AreaId = (ushort)streamReader.ReadUInt32(); streamReader.BaseStream.Position += 72; if (map.Tiles.ContainsKey(index)) map.Tiles[index].Add(chunk); else map.Tiles.TryAdd(index, new List<MapChunk>() { chunk }); offset = Helper.SearchOffset(fileData, streamReader.BaseStream.Position, new byte[] { 0x4B, 0x4E, 0x43, 0x4D }); } }
public void GenerateMapData(Map map) { using (var temp = new BinaryWriter(new MemoryStream())) { foreach (var tile in map.Tiles) { temp.Write(tile.Value.Id); temp.Write(tile.Value.IndexX); temp.Write(tile.Value.IndexY); temp.Write(tile.Value.Chunks.Count); tile.Value.Chunks.ForEach(mc => { temp.Write(mc.IndexX); temp.Write(mc.IndexY); temp.Write(mc.Area); }); } var tileData = (temp.BaseStream as MemoryStream).ToArray(); var compressedTileData = Compress(tileData); MapStream.Write(map.Id); MapStream.Write(map.Name); MapStream.Write(tileData.Length); MapStream.Write(compressedTileData.Length); MapStream.Write(compressedTileData); } }
public MemoryStream Finish(Map map) { Write(map.Tiles.Count, 32); foreach (var kp in map.Tiles) { Write(kp.Key, 13); kp.Value.ForEach(c => { Write(c.IndexX, 5); Write(c.IndexY, 5); Write(c.AreaId, 12); }); } Flush(); return (MemoryStream)streamWriter.BaseStream; }
public void Read(Map map, int x, int y) { var tileId = (ushort)(64 * x + y); map.Tiles = new ConcurrentDictionary<ushort, MapTile>(); map.Tiles.TryAdd(tileId, new MapTile { Id = tileId, IndexX = (byte)x, IndexY = (byte)y, Chunks = new List<MapChunk>() }); var offset = Helper.SearchOffset(fileData, streamReader.BaseStream.Position, new byte[] { 0x4B, 0x4E, 0x43, 0x4D }); while (offset != 0) { streamReader.BaseStream.Position = offset + 12; var chunk = new MapChunk(); chunk.IndexX = (byte)streamReader.ReadUInt32(); chunk.IndexY = (byte)streamReader.ReadUInt32(); streamReader.BaseStream.Position += 40; chunk.Area = (ushort)streamReader.ReadUInt32(); streamReader.BaseStream.Position += 72; if (map.Tiles.ContainsKey(tileId)) map.Tiles[tileId].Chunks.Add(chunk); offset = Helper.SearchOffset(fileData, streamReader.BaseStream.Position, new byte[] { 0x4B, 0x4E, 0x43, 0x4D }); } }
static void ExtractMapData() { Console.WriteLine("Extracting map files..."); if (!File.Exists(structurePath + "Map.lal")) { Console.WriteLine("Can't find structure file 'Map.lal'."); return; } var lalFile = LalParser.Parse(structurePath + "Map.lal"); var lalInfo = LalParser.CreateType(lalFile); var mapDBC = cascHandler.ReadFile(@"DBFilesClient\Map.db2"); var mapDBData = DBReader.Read(mapDBC, lalInfo); var apakStream = new APAKStream(); var writtenMapCount = 0; var apakLock = new object(); var mapOffsets = new Dictionary<ushort, uint>(); Parallel.For(0, mapDBData.Rows.Count, i => { var mapId = Convert.ToUInt16(mapDBData.Rows[i][0]); var mapName = mapDBData.Rows[i][1].ToString(); var mapType = Convert.ToByte(mapDBData.Rows[i][18]); // Skip transport & garrison maps. if (mapType == 3 || mapType == 4) return; var mapReader = new MapReader(); var map = new Map { Id = mapId, Name = mapName }; for (var j = 0; j < 64; j++) { for (var k = 0; k < 64; k++) { var mapData = cascHandler.ReadFile($@"World\Maps\{mapName}\{mapName}_{j}_{k}.adt"); if (mapData != null) { mapReader.Initialize(mapData.ToArray()); mapReader.Read(map, k, j); } } } if (map.Tiles != null) { lock (apakLock) { mapOffsets.Add(map.Id, (uint)(apakStream.BaseStream.Position + apakStream.MapStream.BaseStream.Length)); apakStream.GenerateMapData(map); Console.WriteLine($"Extraction of map '{mapName}' done."); ++writtenMapCount; } } }); foreach (var kp in mapOffsets) apakStream.WriteMapDataOffsets(kp.Key, (uint)(kp.Value + writtenMapCount * 6)); apakStream.Finish(); apakStream.BaseStream.Position = 5; apakStream.Write((ushort)writtenMapCount); File.WriteAllBytes(Directory.GetParent(appFolder) + "/Project-WoW/maps.apak", (apakStream.BaseStream as MemoryStream).ToArray()); Console.WriteLine($"Extracted {writtenMapCount} maps."); }
static void ExtractMapData() { Console.WriteLine("Extracting map files..."); Directory.CreateDirectory("./Project-WoW/Maps"); var mapDBC = cascHandler.ReadFile(@"DBFilesClient\Map.dbc"); var mapDBData = DBReader.Read(mapDBC, typeof(MapDB)); Parallel.For(0, mapDBData.Rows.Count, i => { var mapId = Convert.ToUInt16(mapDBData.Rows[i][0]); var mapName = mapDBData.Rows[i][1].ToString(); var mapType = Convert.ToByte(mapDBData.Rows[i][5]); // Skip transport & garrison maps. if (mapType == 3 || mapType == 4) return; var map = new Map { Id = mapId, Name = mapName }; var mapReader = new MapReader(); // Version 1 // P A M 1 (50 41 4D 01 ) = MAP1 mapReader.Write(new byte[] { 0x50, 0x41, 0x4D, 0x01 }); mapReader.Write(map.Id, 11); mapReader.Write(Encoding.UTF8.GetBytes(mapName).Length, 7); mapReader.Write(Encoding.UTF8.GetBytes(mapName)); mapReader.Flush(); for (var j = 0; j < 64; j++) { for (var k = 0; k < 64; k++) { var mapData = cascHandler.ReadFile($@"World\Maps\{mapName}\{mapName}_{j}_{k}.adt"); if (mapData != null) { mapReader.Initialize(mapData.ToArray()); mapReader.Read(map, k, j); } } } File.WriteAllBytes( $"./Project-WoW/Maps/{map.Id:0000}.map", mapReader.Finish(map).ToArray()); Console.WriteLine($"Extraction of map '{mapName}' done."); }); }