예제 #1
0
        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 });
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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;
        }
예제 #4
0
        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 });
            }
        }
예제 #5
0
        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.");
        }
예제 #6
0
        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.");
            });
        }