Beispiel #1
0
        private static List <TerrainTileEntry> ParseTiles(IEnumerable <uint> offsets, BinaryReader reader)
        {
            var ret  = new List <TerrainTileEntry>();
            var strm = reader.BaseStream;

            foreach (var t in offsets)
            {
                strm.Position = t;
                if (t == 0)
                {
                    ret.Add(null);
                    continue;
                }

                var entry     = new TerrainTileEntry();
                var signature = reader.ReadInt32();
                reader.ReadInt32();
                if (signature != 0x4D415245)
                {
                    ret.Add(null);
                    continue;
                }

                reader.ReadArray <short>(17 * 17 + 16 * 16);

                if (FileManager.Instance.Version <= FileDataVersion.Lichking)
                {
                    signature = reader.ReadInt32();
                    switch (signature)
                    {
                    case 0x4D414F43:
                        entry.MaocData = reader.ReadBytes(reader.ReadInt32());
                        break;

                    case 0x4D41484F:
                        entry.MahoData = reader.ReadBytes(reader.ReadInt32());
                        break;

                    default:
                        strm.Position -= 4;
                        break;
                    }
                }

                ret.Add(entry);
            }

            return(ret);
        }
Beispiel #2
0
        private static unsafe void UpdateWdl(string continent, Action <string, float> progressCallback)
        {
            var preChunks = new Dictionary <int, byte[]>();
            var wdlPath   = string.Format(@"World\Maps\{0}\{0}.wdl", continent);
            List <TerrainTileEntry> existingTiles;
            var mareOffsets = new uint[64 * 64];

            using (var strm = FileManager.Instance.Provider.OpenFile(wdlPath))
            {
                var reader = new BinaryReader(strm);
                while ((strm.Length - strm.Position) > 8)
                {
                    var signature = reader.ReadInt32();
                    var size      = reader.ReadInt32();
                    var data      = reader.ReadBytes(size);
                    // skip the per ADT stuff like MARE, MAOC and MAHO
                    if (signature == 0x4D415245 || signature == 0x4D414F43 ||
                        signature == 0x4D41484F)
                    {
                        continue;
                    }

                    if (preChunks.ContainsKey(signature))
                    {
                        continue;
                    }

                    preChunks.Add(signature, data);
                }

                byte[] offsetBytes;
                preChunks.TryGetValue(0x4D414F46, out offsetBytes);
                if (offsetBytes != null)
                {
                    fixed(uint *ptr = mareOffsets)
                    {
                        fixed(byte *bptr = offsetBytes)
                        {
                            UnsafeNativeMethods.CopyMemory((byte *)ptr, bptr, 64 * 64 * 4);
                        }
                    }
                }

                existingTiles = ParseTiles(mareOffsets, reader);
            }

            using (var strm = FileManager.Instance.GetOutputStream(wdlPath))
            {
                var writer = new BinaryWriter(strm);
                foreach (var pair in preChunks.Where(pair => pair.Key != 0x4D414F46))
                {
                    writer.Write(pair.Key);
                    writer.Write(pair.Value.Length);
                    writer.Write(pair.Value);
                }

                var marePos = writer.BaseStream.Position;
                writer.Write(0x4D414F46);
                writer.Write(mareOffsets.Length * 4);
                writer.WriteArray(mareOffsets);

                for (var i = 0; i < 64 * 64; ++i)
                {
                    progressCallback(string.Format("Processing {0}_{1}_{2}.adt...", continent, i % 64, i / 64), i / 4096.0f);
                    var existing = existingTiles[i];
                    var heights  = GetMareEntry(continent, i % 64, i / 64);
                    if (heights == null)
                    {
                        mareOffsets[i] = 0;
                        continue;
                    }

                    if (existing == null)
                    {
                        existing = new TerrainTileEntry();
                    }

                    mareOffsets[i] = (uint)writer.BaseStream.Position;
                    writer.Write(0x4D415245);
                    writer.Write(heights.Length * 2);
                    writer.WriteArray(heights);

                    if (existing.MaocData != null)
                    {
                        writer.Write(0x4D414F43);
                        writer.Write(existing.MaocData.Length);
                        writer.Write(existing.MaocData);
                    }

                    if (existing.MahoData != null)
                    {
                        writer.Write(0x4D41484F);
                        writer.Write(existing.MahoData.Length);
                        writer.Write(existing.MahoData);
                    }
                }

                writer.BaseStream.Position = marePos + 8;
                writer.WriteArray(mareOffsets);
            }
        }