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."); }); }
static void ExtractMaps() { ExtractDbcFiles(); ExtractCameraFiles(); ExtractGameTablesFiles(); Console.WriteLine("Extracting maps..."); string path = $"{BaseDirectory}/maps"; CreateDirectory(path); Console.WriteLine("Convert map files"); int count = 1; Console.WriteLine("Loading DB2 files"); var mapStorage = DBReader.Read <MapRecord>("DBFilesClient\\Map.db2"); if (mapStorage == null) { Console.WriteLine("Fatal error: Invalid Map.db2 file format!"); return; } foreach (var record in mapStorage.Values) { Console.Write($"Extract {record.Directory} ({count++}/{mapStorage.Count}) \n"); // Loadup map grid data string storagePath = $"World\\Maps\\{record.Directory}\\{record.Directory}.wdt"; ChunkedFile wdt = new ChunkedFile(); if (wdt.loadFile(CascHandler, storagePath)) { wdt_MAIN main = wdt.GetChunk("MAIN").As <wdt_MAIN>(); for (int y = 0; y < 64; ++y) { for (int x = 0; x < 64; ++x) { if (Convert.ToBoolean(main.adt_list[y][x].flag & 0x1)) { storagePath = $"World\\Maps\\{record.Directory}\\{record.Directory}_{x}_{y}.adt"; string outputFileName = $"{path}/{record.Id:D4}_{y:D2}_{x:D2}.map"; MapFile.ConvertADT(CascHandler, storagePath, outputFileName, y, x, MapFile.IsDeepWaterIgnored(record.Id, y, x)); } } // draw progress bar Console.Write($"Processing........................{(100 * (y + 1)) / 64}%\r"); } } } Console.WriteLine("\n"); }
static bool LoadRequiredDb2Files() { LiquidMaterialStorage = DBReader.Read <LiquidMaterialRecord>(1132538); if (LiquidMaterialStorage == null) { Console.WriteLine("Fatal error: Invalid LiquidMaterial.db2 file format!"); return(false); } LiquidTypeStorage = DBReader.Read <LiquidTypeRecord>(1371380); if (LiquidTypeStorage == null) { Console.WriteLine("Fatal error: Invalid LiquidType.db2 file format!\n"); return(false); } return(true); }
static void ExtractCameraFiles() { Dictionary <uint, CinematicCameraRecord> storage = DBReader.Read <CinematicCameraRecord>("DBFilesClient\\CinematicCamera.db2"); if (storage == null) { Console.WriteLine("Invalid CinematicCamera.db2 file format. Camera extract aborted.\n"); return; } Console.WriteLine($"Extracting ({storage.Values.Count} CinematicCameras!)\n"); string path = $"{BaseDirectory}/cameras"; CreateDirectory(path); // extract M2s uint count = 0; foreach (var cameraRecord in storage.Values) { var cameraStream = CascHandler.OpenFile((int)cameraRecord.ModelFileDataID); if (cameraStream != null) { string file = path + $"/FILE{cameraRecord.ModelFileDataID:X8}.xxx"; if (!File.Exists(file)) { FileWriter.WriteFile(cameraStream, file); ++count; } } else { Console.WriteLine($"Unable to open file {$"File{cameraRecord.ModelFileDataID:X8}.xxx"} in the archive: \n"); } } Console.WriteLine($"Extracted {count} Camera files."); }
static void ExtractMMaps(string[] args) { if (!Directory.Exists("maps") || Directory.GetFiles("maps").Length == 0) { Console.WriteLine("'maps' directory is empty or does not exist"); return; } if (!Directory.Exists("vmaps") || Directory.GetFiles("vmaps").Length == 0) { Console.WriteLine("'vmaps' directory is empty or does not exist"); return; } CreateDirectory("mmaps_new"); //handle args bool debugMaps = false; int mapId = -1; for (var i = 1; i < args.Length; ++i) { switch (args[i].ToLower()) { case "-debug": CreateDirectory("mmaps/meshes"); debugMaps = true; break; case "-id": mapId = int.Parse(args[i + 1]); i++; break; } } Console.WriteLine("Extracting MMap files..."); var vm = new Framework.Collision.VMapManager2(); var mapStorage = DBReader.Read <MapRecord>("DBFilesClient\\Map.db2"); if (mapStorage == null) { Console.WriteLine("Fatal error: Invalid Map.db2 file format!\n"); return; } MultiMap <uint, uint> mapData = new MultiMap <uint, uint>(); foreach (var record in mapStorage.Values) { if (record.ParentMapID != -1) { mapData.Add((uint)record.ParentMapID, record.Id); } } vm.Initialize(mapData); MapBuilder builder = new MapBuilder(vm, debugMaps); var watch = System.Diagnostics.Stopwatch.StartNew(); if (mapId != -1) { builder.buildMap((uint)mapId); } else { builder.buildAllMaps(); } Console.WriteLine($"Finished. MMAPS were built in {watch.ElapsedMilliseconds} ms!"); }
static void ExtractMaps() { ExtractDbcFiles(); ExtractCameraFiles(); ExtractGameTablesFiles(); Console.WriteLine("Extracting maps..."); string path = $"{BaseDirectory}/maps"; CreateDirectory(path); Console.WriteLine("Convert map files"); int count = 1; Console.WriteLine("Loading DB2 files"); var mapStorage = DBReader.Read <MapRecord>(1349477); if (mapStorage == null) { Console.WriteLine("Fatal error: Invalid Map.db2 file format!"); return; } foreach (var record in mapStorage.Values) { if (record.WdtFileDataID == 0) { continue; } Console.Write($"Extract {record.Directory} ({count++}/{mapStorage.Count}) \n"); // Loadup map grid data ChunkedFile wdt = new(); BitArray existingTiles = new(64 * 64); if (wdt.LoadFile(CascHandler, (uint)record.WdtFileDataID, $"WDT for map {record.Id}")) { MPHD mphd = wdt.GetChunk("MPHD").As <MPHD>(); MAIN main = wdt.GetChunk("MAIN").As <MAIN>(); for (int y = 0; y < 64; ++y) { for (int x = 0; x < 64; ++x) { if ((main.MapAreaInfo[y][x].Flag & 0x1) == 0) { continue; } string outputFileName = $"{path}/{record.Id:D4}_{y:D2}_{x:D2}.map"; bool ignoreDeepWater = MapFile.IsDeepWaterIgnored(record.Id, y, x); if (mphd != null && (mphd.Flags & 0x200) != 0) { MAID maid = wdt.GetChunk("MAID").As <MAID>(); existingTiles[y * 64 + x] = MapFile.ConvertADT(CascHandler, maid.MapFileDataIDs[y][x].RootADT, record.MapName, outputFileName, y, x, ignoreDeepWater); } else { string storagePath = $"World\\Maps\\{record.Directory}\\{record.Directory}_{x}_{y}.adt"; existingTiles[y * 64 + x] = MapFile.ConvertADT(CascHandler, storagePath, record.MapName, outputFileName, y, x, ignoreDeepWater); } } // draw progress bar Console.Write($"Processing........................{(100 * (y + 1)) / 64}%\r"); } } using BinaryWriter binaryWriter = new(File.Open($"{path}/{record.Id:D4}.tilelist", FileMode.Create, FileAccess.Write)); binaryWriter.Write(SharedConst.MAP_MAGIC); binaryWriter.Write(SharedConst.MAP_VERSION_MAGIC); binaryWriter.Write(_build); binaryWriter.WriteString(existingTiles.ToBinaryString()); } Console.WriteLine("\n"); }
static void ExtractClientDBData(string[] args) { Console.WriteLine("Searching for available ClientDB (dbc & db2) files..."); var fileList = new List <string>(); var wowBin = cascHandler.BasePath + "/Wow.exe"; var wowBBin = cascHandler.BasePath + "/WowB.exe"; var wowTBin = cascHandler.BasePath + "/WowT.exe"; var wowXBin = cascHandler.BasePath + "/World of Warcraft"; var bin = ""; if (File.Exists(wowBin)) { bin = wowBin; } else if (File.Exists(wowTBin)) { bin = wowTBin; } else if (File.Exists(wowXBin)) { bin = wowXBin; } else if (File.Exists(wowBBin)) { bin = wowBBin; } else { Console.WriteLine("No valid World of Warcraft version found."); Console.ReadKey(); return; } // Get dbc files from wow bin using (var sr = new StreamReader(bin)) { var text = sr.ReadToEnd(); foreach (Match dbc in Regex.Matches(text, @"DBFilesClient\\([A-Za-z0-9\-_]+)\.(dbc|db2)")) { fileList.Add(dbc.Value.Replace(@"\\", @"\")); } } // add missing dbc/db2 file names. FileList.ClientDBFileNames.ForEach(f => { if (!fileList.Contains(f)) { fileList.Add(f); } }); Console.WriteLine("Getting available locales..."); var locales = new Dictionary <string, Locales>(); if (args.Length == 1) { locales.Add(args[0], (Locales)Enum.Parse(typeof(Locales), args[0])); } else { var buildInfo = File.ReadAllText(cascHandler.BasePath + "/.build.info").Split(new[] { '|' })[21]; var buildInfoLocales = Regex.Matches(buildInfo, " ([A-Za-z]{4}) speech"); foreach (Match m in buildInfoLocales) { var flagString = m.Value.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0]; var localFlag = (Locales)Enum.Parse(typeof(Locales), flagString); if (!locales.ContainsKey(flagString)) { locales.Add(flagString, localFlag); Console.WriteLine($"Found locale '{flagString}'."); } } } Directory.CreateDirectory("./Project-WoW/ClientDB/SQL"); Directory.CreateDirectory("./Project-WoW/ClientDB/Files"); /// Files Console.WriteLine("Extracting files..."); var fileCtr = 0; var fileErrors = new List <string>(); foreach (var file in fileList) { var nameOnly = file.Replace(@"\\", "").Replace(@"DBFilesClient\", ""); foreach (var locale in locales) { var dbStream = cascHandler.ReadFile(file, locale.Value); Console.Write($"Writing file {nameOnly} ({locale.Key})..."); if (dbStream != null) { Directory.CreateDirectory($"./Project-WoW/ClientDB/Files/{locale.Key}"); Task.Run(() => FileWriter.WriteFile(dbStream, $"./Project-WoW/ClientDB/Files/{locale.Key}/{nameOnly}")); Console.ForegroundColor = ConsoleColor.Green; Console.Write("Done."); Console.WriteLine(); fileCtr++; } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Error."); fileErrors.Add($"{nameOnly} ({locale.Key})"); } Console.ForegroundColor = ConsoleColor.Gray; } } Console.WriteLine($"Extracted {fileCtr} files."); Console.WriteLine(); Console.WriteLine("Getting structures..."); var existingStructList = new List <string>(); var structsPath = cascHandler.BasePath + "/Structures/"; if (!Directory.Exists(structsPath)) { Directory.CreateDirectory(structsPath); } var structureNames = Directory.GetFiles(structsPath); var structureNameList = new List <string>(structureNames.Length); foreach (var s in structureNames) { structureNameList.Add(Path.GetFileNameWithoutExtension(s)); } foreach (var s in fileList) { var nameOnly = s.Replace(@"\\", "").Replace(@"DBFilesClient\", "").Replace(@".dbc", "").Replace(@".db2", ""); if (structureNameList.Contains(nameOnly)) { existingStructList.Add(s); } } Console.WriteLine($"Found {existingStructList.Count} structures."); Console.WriteLine(); #pragma warning disable CS0618 AppDomain.CurrentDomain.AppendPrivatePath(Environment.CurrentDirectory); #pragma warning restore CS0618 Console.WriteLine("Generating SQL data..."); Console.WriteLine(); var fileLock = new object(); var generatedTables = new List <string>(); var counter = 0; var noLocaleMSSQL = new StreamWriter($"./Project-WoW/ClientDB/SQL/DataDB.MSSQL.sql"); var noLocaleMYSQL = new StreamWriter($"./Project-WoW/ClientDB/SQL/DataDB.MYSQL.sql"); foreach (var locale in locales) { var localeMSSQL = new StreamWriter($"./Project-WoW/ClientDB/SQL/{locale.Key}_DataDB.MSSQL.sql"); var localeMYSQL = new StreamWriter($"./Project-WoW/ClientDB/SQL/{locale.Key}_DataDB.MYSQL.sql"); foreach (var file in existingStructList) { var nameOnly = file.Replace(@"\\", "").Replace(@"DBFilesClient\", ""); var path = $"./Project-WoW/ClientDB/Files/{locale.Key}/{nameOnly}"; if (!File.Exists(path)) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"{path} doesn't exist."); Console.WriteLine("Skip it."); continue; } var dbStream = new MemoryStream(File.ReadAllBytes(path)); if (dbStream != null) { nameOnly = nameOnly.Replace(@".dbc", "").Replace(@".db2", ""); var ccp = new CSharpCodeProvider(); var paramss = new CompilerParameters(); paramss.GenerateExecutable = false; paramss.GenerateInMemory = true; paramss.ReferencedAssemblies.Add("DataExtractor.exe"); var file1 = File.ReadAllText(structsPath + nameOnly + ".cs"); var code = new[] { file1 }; var result = ccp.CompileAssemblyFromSource(paramss, code); var type = result.CompiledAssembly.GetTypes()[0]; var hasStringProperties = type.GetProperties().Any(p => p.PropertyType == typeof(string)); var pluralized = nameOnly.Replace(@".dbc", "").Replace(@".db2", ""); if (!pluralizationExceptions.Contains(pluralized)) { pluralized = pluralized.Pluralize(); } pluralized.Insert(0, pluralized[0].ToString().ToUpperInvariant()); pluralized.Remove(1); if (hasStringProperties) { pluralized = pluralized + "_" + locale.Key; } if (!generatedTables.Contains(pluralized)) { generatedTables.Add(pluralized); if (hasStringProperties) { Console.Write($"Generating SQL data for {pluralized} ({locale.Key})..."); } else { Console.Write($"Generating SQL data for {pluralized}..."); } var dbTable = DBReader.Read(dbStream, type); lock (fileLock) { if (hasStringProperties) { localeMYSQL.Write(GenerateMYSQLData(nameOnly, pluralized, dbTable)); localeMSSQL.Write(GenerateMSSQLData(pluralized, dbTable)); } else { noLocaleMYSQL.Write(GenerateMYSQLData(nameOnly, pluralized, dbTable)); noLocaleMSSQL.Write(GenerateMSSQLData(pluralized, dbTable)); } } counter++; Console.ForegroundColor = ConsoleColor.Green; Console.Write("Done."); Console.WriteLine(); } } Console.ForegroundColor = ConsoleColor.Gray; } localeMSSQL.Dispose(); localeMYSQL.Dispose(); } noLocaleMSSQL.Dispose(); noLocaleMYSQL.Dispose(); Console.WriteLine("Generated Sql data for {0} ClientDB(s).", existingStructList.Count); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(); if (fileErrors.Count > 0) { Console.WriteLine("ERROS WHILE EXTRACTING:"); foreach (var s in fileErrors) { Console.WriteLine(s); } } Console.ForegroundColor = ConsoleColor.Gray; }
static void ExtractMapData() { Console.WriteLine("Extracting map files..."); Directory.CreateDirectory("./Project-WoW/Maps"); var mapDBC = cascHandler.ReadFile(@"DBFilesClient\Map.db2"); var mapDBData = DBReader.Read(mapDBC, typeof(MapDB)); 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][5]); // 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/adt.apak", (apakStream.BaseStream as MemoryStream).ToArray()); }
static void ExtractMaps() { ExtractDbcFiles(); ExtractCameraFiles(); ExtractGameTablesFiles(); Console.WriteLine("Extracting maps..."); string path = $"{BaseDirectory}/maps"; CreateDirectory(path); Console.WriteLine("Convert map files"); int count = 1; Console.WriteLine("Loading DB2 files"); var mapStorage = DBReader.Read <MapRecord>(1349477); if (mapStorage == null) { Console.WriteLine("Fatal error: Invalid Map.db2 file format!"); return; } foreach (var record in mapStorage.Values) { Console.Write($"Extract {record.Directory} ({count++}/{mapStorage.Count}) \n"); // Loadup map grid data ChunkedFile wdt = new ChunkedFile(); if (wdt.loadFile(CascHandler, record.WdtFileDataID, $"WDT for map {record.Id}")) { wdt_MPHD mphd = wdt.GetChunk("MPHD").As <wdt_MPHD>(); wdt_MAIN main = wdt.GetChunk("MAIN").As <wdt_MAIN>(); for (int y = 0; y < 64; ++y) { for (int x = 0; x < 64; ++x) { if (!Convert.ToBoolean(main.adt_list[y][x].flag & 0x1)) { continue; } string outputFileName = $"{path}/{record.Id:D4}_{y:D2}_{x:D2}.map"; bool ignoreDeepWater = MapFile.IsDeepWaterIgnored(record.Id, y, x); if (mphd != null && (mphd.flags & 0x200) != 0) { wdt_MAID maid = wdt.GetChunk("MAID").As <wdt_MAID>(); MapFile.ConvertADT(CascHandler, maid.adt_files[y][x].rootADT, record.MapName, outputFileName, y, x, ignoreDeepWater); } else { string storagePath = $"World\\Maps\\{record.Directory}\\{record.Directory}_{x}_{y}.adt"; MapFile.ConvertADT(CascHandler, storagePath, record.MapName, outputFileName, y, x, ignoreDeepWater); } } // draw progress bar Console.Write($"Processing........................{(100 * (y + 1)) / 64}%\r"); } } } Console.WriteLine("\n"); }
public static bool LoadFiles(CASCHandler handler) { //CinematicCamera using (MemoryStream stream = handler.ReadFile("DBFilesClient\\CinematicCamera.db2")) { if (stream == null) { Console.WriteLine("Unable to open file DBFilesClient\\CinematicCamera.db2s in the archive"); return(false); } Dictionary <uint, CinematicCameraRecord> storage = DBReader.Read <CinematicCameraRecord>(stream); if (storage == null) { Console.WriteLine("Invalid CinematicCamera.db2 file format. Camera extract aborted.\n"); return(false); } // get camera file list from DB2 foreach (var record in storage.Values) { CameraFileNames.Add(record.ModelFileDataID); } storage = null; } using (MemoryStream stream = Program.cascHandler.ReadFile("DBFilesClient\\GameObjectDisplayInfo.db2")) { if (stream == null) { Console.WriteLine("Unable to open file DBFilesClient\\GameObjectDisplayInfo.db2 in the archive\n"); return(false); } GameObjectDisplayInfoStorage = DBReader.Read <GameObjectDisplayInfoRecord>(stream); if (GameObjectDisplayInfoStorage == null) { Console.WriteLine("Fatal error: Invalid GameObjectDisplayInfo.db2 file format!\n"); return(false); } } //Map using (MemoryStream stream = handler.ReadFile("DBFilesClient\\Map.db2")) { if (stream == null) { Console.WriteLine("Unable to open file DBFilesClient\\Map.db2 in the archive\n"); return(false); } MapStorage = DBReader.Read <MapRecord>(stream); if (MapStorage == null) { Console.WriteLine("Fatal error: Invalid Map.db2 file format!\n"); return(false); } } //LiquidMaterial using (MemoryStream stream = handler.ReadFile("DBFilesClient\\LiquidMaterial.db2")) { if (stream == null) { Console.WriteLine("Unable to open file DBFilesClient\\LiquidMaterial.db2 in the archive\n"); return(false); } var storage = DBReader.Read <LiquidMaterialRecord>(stream); if (storage == null) { Console.WriteLine("Fatal error: Invalid LiquidMaterial.db2 file format!\n"); return(false); } foreach (var record in storage.Values) { LiquidMaterials[record.Id] = record.LVF; } storage = null; } //LiquidObject using (MemoryStream stream = handler.ReadFile("DBFilesClient\\LiquidObject.db2")) { if (stream == null) { Console.WriteLine("Unable to open file DBFilesClient\\LiquidObject.db2 in the archive\n"); return(false); } var storage = DBReader.Read <LiquidObjectRecord>(stream); if (storage == null) { Console.WriteLine("Fatal error: Invalid LiquidObject.db2 file format!\n"); return(false); } foreach (var record in storage.Values) { LiquidObjects[record.Id] = record.LiquidTypeID; } storage = null; } //LiquidType using (MemoryStream stream = handler.ReadFile("DBFilesClient\\LiquidType.db2")) { if (stream == null) { Console.WriteLine("Unable to open file DBFilesClient\\LiquidType.db2 in the archive\n"); return(false); } var storage = DBReader.Read <LiquidTypeRecord>(stream); if (storage == null) { Console.WriteLine("Fatal error: Invalid LiquidType.db2 file format!\n"); return(false); } foreach (var record in storage.Values) { LiquidTypeEntry liquidType = new LiquidTypeEntry(); liquidType.SoundBank = record.SoundBank; liquidType.MaterialID = record.MaterialID; LiquidTypes[record.Id] = liquidType; } storage = null; } return(true); }