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); }
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); } }