private void toolStripExtractMEMMenuItem(MeType gameType) { using (OpenFileDialog modFile = new OpenFileDialog()) { modFile.Title = "Please select Mod file"; modFile.Filter = "MEM mod file | *.mem"; modFile.Multiselect = true; if (modFile.ShowDialog() != DialogResult.OK) { return; } using (FolderBrowserDialog modDir = new FolderBrowserDialog()) { modDir.Description = "Please select destination directory for MEM extraction"; if (modDir.ShowDialog() != DialogResult.OK) { return; } enableGameDataMenu(false); GameData.gameType = gameType; string errors = ""; string log = ""; string[] files = modFile.FileNames; long diskFreeSpace = Misc.getDiskFreeSpace(modDir.SelectedPath); long diskUsage = 0; foreach (string file in files) { diskUsage += new FileInfo(file).Length; } diskUsage = (long)(diskUsage * 2.5); if (diskUsage >= diskFreeSpace) { MessageBox.Show("You have not enough disk space remaining. You need about " + Misc.getBytesFormat(diskUsage) + " free."); } else { Misc.startTimer(); foreach (string file in files) { string outDir = Path.Combine(modDir.SelectedPath, Path.GetFileNameWithoutExtension(file)); Directory.CreateDirectory(outDir); updateStatusLabel("MOD: " + file + " - extracting..."); updateStatusLabel2(""); errors += new MipMaps().extractTextureMod(file, outDir, null, null, ref log); } var time = Misc.stopTimer(); updateStatusLabel("MODs extracted. Process total time: " + Misc.getTimerFormat(time)); updateStatusLabel2(""); if (errors != "") { MessageBox.Show("WARNING: Some errors have occured!"); } } } } enableGameDataMenu(true); }
public Installer() { InitializeComponent(); Text = "MEM Installer v" + Application.ProductVersion + " for ALOT"; mipMaps = new MipMaps(); treeScan = new TreeScan(); cachePackageMgr = new CachePackageMgr(null, this); }
private void replaceTexture() { if (listViewTextures.SelectedItems.Count == 0) { return; } using (OpenFileDialog selectDDS = new OpenFileDialog()) { selectDDS.Title = "Please select DDS file"; selectDDS.Filter = "DDS file|*.dds"; if (selectDDS.ShowDialog() != DialogResult.OK) { return; } DDSImage image = new DDSImage(selectDDS.FileName); if (!image.checkExistAllMipmaps()) { MessageBox.Show("This texture has not all the required mipmaps, canceling..."); return; } bool loadMod = loadMODsToolStripMenuItem.Enabled; bool clearMod = clearMODsToolStripMenuItem.Enabled; bool packMod = packMODToolStripMenuItem.Enabled; EnableMenuOptions(false); PackageTreeNode node = (PackageTreeNode)treeViewPackages.SelectedNode; ListViewItem item = listViewTextures.FocusedItem; int index = Convert.ToInt32(item.Name); MipMaps mipMaps = new MipMaps(); richTextBoxInfo.Text = mipMaps.replaceTexture(image, node.textures[index].list, cachePackageMgr, node.textures[index].name, node.textures[index].crc); if (richTextBoxInfo.Text != "") { richTextBoxInfo.Show(); pictureBoxPreview.Hide(); MessageBox.Show("WARNING: Some errors have occured!"); } cachePackageMgr.CloseAllWithSave(); EnableMenuOptions(true); loadMODsToolStripMenuItem.Enabled = loadMod; clearMODsToolStripMenuItem.Enabled = clearMod; packMODToolStripMenuItem.Enabled = packMod; listViewTextures.Focus(); item.Selected = false; item.Selected = true; item.Focused = true; } }
public string PrepareListOfTextures(TexExplorer texEplorer, CachePackageMgr cachePackageMgr, MainWindow mainWindow, Installer installer, ref string log, bool force = false) { string errors = ""; treeScan = null; List <FoundTexture> textures = new List <FoundTexture>(); string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Assembly.GetExecutingAssembly().GetName().Name); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string filename = Path.Combine(path, "me" + (int)GameData.gameType + "map.bin"); if (force && File.Exists(filename)) { File.Delete(filename); } if (File.Exists(filename)) { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite)) { uint tag = fs.ReadUInt32(); uint version = fs.ReadUInt32(); if (tag != TexExplorer.textureMapBinTag || version != TexExplorer.textureMapBinVersion) { if (mainWindow != null) { MessageBox.Show("Wrong " + filename + " file!"); mainWindow.updateStatusLabel(""); mainWindow.updateStatusLabel2(""); texEplorer.Close(); } fs.Close(); log += "Wrong " + filename + " file!" + Environment.NewLine; return("Wrong " + filename + " file!" + Environment.NewLine); } uint countTexture = fs.ReadUInt32(); for (int i = 0; i < countTexture; i++) { FoundTexture texture = new FoundTexture(); texture.name = fs.ReadStringASCIINull(); texture.crc = fs.ReadUInt32(); texture.packageName = fs.ReadStringASCIINull(); uint countPackages = fs.ReadUInt32(); texture.list = new List <MatchedTexture>(); for (int k = 0; k < countPackages; k++) { MatchedTexture matched = new MatchedTexture(); matched.exportID = fs.ReadInt32(); matched.path = fs.ReadStringASCIINull(); texture.list.Add(matched); } textures.Add(texture); } if (fs.Position < new FileInfo(filename).Length) { List <string> packages = new List <string>(); int numPackages = fs.ReadInt32(); for (int i = 0; i < numPackages; i++) { string pkgPath = fs.ReadStringASCIINull(); pkgPath = GameData.GamePath + pkgPath; packages.Add(pkgPath); } for (int i = 0; i < packages.Count; i++) { if (GameData.packageFiles.Find(s => s.Equals(packages[i], StringComparison.OrdinalIgnoreCase)) == null) { if (mainWindow != null) { MessageBox.Show("Detected removal of game files since last game data scan." + "\n\nYou need to restore the game to vanilla state and reinstall vanilla DLCs and DLC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); return(""); } else if (!force) { errors += "Detected removal of game files since last game data scan." + Environment.NewLine + Environment.NewLine + "You need to restore the game to vanilla state and reinstall vanilla DLCs and DLC mods."; return(""); } } } for (int i = 0; i < GameData.packageFiles.Count; i++) { if (packages.Find(s => s.Equals(GameData.packageFiles[i], StringComparison.OrdinalIgnoreCase)) == null) { if (mainWindow != null) { MessageBox.Show("Detected additional game files not present in latest game data scan." + "\n\nYou need to restore the game to vanilla state and reinstall vanilla DLCs and DLC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); return(""); } else if (!force) { errors += "Detected additional game files not present in latest game data scan." + Environment.NewLine + Environment.NewLine + "You need to restore the game to vanilla state and reinstall vanilla DLCs and DLC mods."; return(""); } } } } else { fs.SeekEnd(); fs.WriteInt32(GameData.packageFiles.Count); for (int i = 0; i < GameData.packageFiles.Count; i++) { fs.WriteStringASCIINull(GameData.RelativeGameData(GameData.packageFiles[i])); } } treeScan = textures; if (mainWindow != null) { mainWindow.updateStatusLabel(""); mainWindow.updateStatusLabel2(""); } return(errors); } } if (File.Exists(filename)) { File.Delete(filename); } if (Misc.detectBrokenMod(GameData.gameType)) { if (mainWindow != null) { MessageBox.Show("Detected ME1 Controller or/and Faster Elevators mod!\nMEM will not work properly due broken content in mod."); } return(""); } if (MipMaps.checkGameDataModded(cachePackageMgr)) { if (mainWindow != null) { MessageBox.Show("Detected modded game. Can not continue." + "\n\nYou need to restore the game to vanilla state and reinstall vanilla DLCs and DLC mods." + "\n\nThen start Texture Manager again."); return(""); } else if (!force) { errors += "Detected modded game. Can not continue." + Environment.NewLine + Environment.NewLine + "You need to restore the game to vanilla state and reinstall vanilla DLCs and DLC mods."; return(""); } } if (mainWindow != null) { DialogResult result = MessageBox.Show("Replacing textures and creating mods requires generating a map of the game's textures.\n" + "You only need to do it once.\n\n" + "IMPORTANT! Your game needs to be in vanilla state and have all original DLCs and DLC mods installed.\n\n" + "Are you sure you want to proceed?", "Textures mapping", MessageBoxButtons.YesNo); if (result == DialogResult.No) { texEplorer.Close(); return(""); } } GameData.packageFiles.Sort(); if (mainWindow != null) { Misc.startTimer(); } for (int i = 0; i < GameData.packageFiles.Count; i++) { if (mainWindow != null) { mainWindow.updateStatusLabel("Finding textures in package " + (i + 1) + " of " + GameData.packageFiles.Count + " - " + GameData.packageFiles[i]); } if (installer != null) { installer.updateStatusScan("Progress... " + (i * 100 / GameData.packageFiles.Count) + " % "); } errors += FindTextures(textures, GameData.packageFiles[i], cachePackageMgr, ref log); } using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) { fs.WriteUInt32(TexExplorer.textureMapBinTag); fs.WriteUInt32(TexExplorer.textureMapBinVersion); fs.WriteInt32(textures.Count); for (int i = 0; i < textures.Count; i++) { fs.WriteStringASCIINull(textures[i].name); fs.WriteUInt32(textures[i].crc); fs.WriteStringASCIINull(textures[i].packageName); fs.WriteInt32(textures[i].list.Count); for (int k = 0; k < textures[i].list.Count; k++) { fs.WriteInt32(textures[i].list[k].exportID); fs.WriteStringASCIINull(textures[i].list[k].path); } } fs.WriteInt32(GameData.packageFiles.Count); for (int i = 0; i < GameData.packageFiles.Count; i++) { fs.WriteStringASCIINull(GameData.RelativeGameData(GameData.packageFiles[i])); } } if (mainWindow != null) { MipMaps mipmaps = new MipMaps(); if (GameData.gameType == MeType.ME1_TYPE) { errors += mipmaps.removeMipMapsME1(1, textures, null, mainWindow, null); errors += mipmaps.removeMipMapsME1(2, textures, null, mainWindow, null); } else { errors += mipmaps.removeMipMapsME2ME3(textures, null, mainWindow, null); } var time = Misc.stopTimer(); mainWindow.updateStatusLabel("Done. Process total time: " + Misc.getTimerFormat(time)); mainWindow.updateStatusLabel2(""); } treeScan = textures; return(errors); }
static private string convertDataModtoMem(string inputDir, string memFilePath) { string errors = ""; string[] files = null; Console.WriteLine("Mods conversion started..."); List <string> list = Directory.GetFiles(inputDir, "*.tpf").Where(item => item.EndsWith(".tpf", StringComparison.OrdinalIgnoreCase)).ToList(); list.AddRange(Directory.GetFiles(inputDir, "*.mod").Where(item => item.EndsWith(".mod", StringComparison.OrdinalIgnoreCase))); list.AddRange(Directory.GetFiles(inputDir, "*.dds").Where(item => item.EndsWith(".dds", StringComparison.OrdinalIgnoreCase))); list.Sort(); files = list.ToArray(); int result; string fileName = ""; uint dstLen = 0; string[] ddsList = null; ulong numEntries = 0; List <TexExplorer.BinaryMod> mods = new List <TexExplorer.BinaryMod>(); foreach (string file in files) { if (file.EndsWith(".mod", StringComparison.OrdinalIgnoreCase)) { try { using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { string package = ""; int len = fs.ReadInt32(); string version = fs.ReadStringASCII(len); // version if (version.Length < 5) // legacy .mod { fs.SeekBegin(); } numEntries = fs.ReadUInt32(); for (uint i = 0; i < numEntries; i++) { TexExplorer.BinaryMod mod = new TexExplorer.BinaryMod(); len = fs.ReadInt32(); string desc = fs.ReadStringASCII(len); // description len = fs.ReadInt32(); string scriptLegacy = fs.ReadStringASCII(len); string path = ""; if (desc.Contains("Binary Replacement")) { try { Misc.ParseME3xBinaryScriptMod(scriptLegacy, ref package, ref mod.exportId, ref path); if (mod.exportId == -1 || package == "" || path == "") { throw new Exception(); } } catch { len = fs.ReadInt32(); fs.Skip(len); errors += "Skipping not compatible content, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; continue; } mod.packagePath = GameData.RelativeGameData(Path.Combine(path, package)); mod.binaryMod = true; len = fs.ReadInt32(); mod.data = fs.ReadToBuffer(len); } else { string textureName = desc.Split(' ').Last(); FoundTexture f; try { f = Misc.ParseLegacyMe3xScriptMod(textures, scriptLegacy, textureName); mod.textureCrc = f.crc; if (mod.textureCrc == 0) { throw new Exception(); } } catch { len = fs.ReadInt32(); fs.Skip(len); errors += "Skipping not compatible content, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; continue; } textureName = f.name; mod.textureName = textureName; mod.binaryMod = false; len = fs.ReadInt32(); mod.data = fs.ReadToBuffer(len); DDSImage image = new DDSImage(new MemoryStream(mod.data)); if (!image.checkExistAllMipmaps()) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", f.crc) + " This texture has not all the required mipmaps, skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; continue; } Package pkg = new Package(GameData.GamePath + f.list[0].path); Texture texture = new Texture(pkg, f.list[0].exportID, pkg.getExportData(f.list[0].exportID)); if (texture.mipMapsList.Count > 1 && image.mipMaps.Count() <= 1) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", f.crc) + " This texture must have mipmaps, skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; continue; } string fmt = texture.properties.getProperty("Format").valueName; DDSFormat ddsFormat = DDSImage.convertFormat(fmt); if (image.ddsFormat != ddsFormat) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", f.crc) + " This texture has wrong texture format, should be: " + ddsFormat + ", skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; continue; } if (image.mipMaps[0].origWidth / image.mipMaps[0].origHeight != texture.mipMapsList[0].width / texture.mipMapsList[0].height) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", f.crc) + " This texture has wrong aspect ratio, skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; continue; } } mods.Add(mod); } } } catch { errors += "Mod is not compatible: " + file + Environment.NewLine; continue; } } else if (file.EndsWith(".tpf", StringComparison.OrdinalIgnoreCase)) { IntPtr handle = IntPtr.Zero; try { byte[] buffer = File.ReadAllBytes(file); handle = ZlibHelper.Zip.Open(buffer, ref numEntries, 1); if (ZlibHelper.Zip.LocateFile(handle, "texmod.def") != 0) { throw new Exception(); } result = ZlibHelper.Zip.GetCurrentFileInfo(handle, ref fileName, ref dstLen); if (result != 0) { throw new Exception(); } byte[] listText = new byte[dstLen]; result = ZlibHelper.Zip.ReadCurrentFile(handle, listText, dstLen); if (result != 0) { throw new Exception(); } ddsList = Encoding.ASCII.GetString(listText).Trim('\0').Replace("\r", "").TrimEnd('\n').Split('\n'); result = ZlibHelper.Zip.GoToFirstFile(handle); if (result != 0) { throw new Exception(); } for (uint i = 0; i < numEntries; i++) { TexExplorer.BinaryMod mod = new TexExplorer.BinaryMod(); try { uint crc = 0; result = ZlibHelper.Zip.GetCurrentFileInfo(handle, ref fileName, ref dstLen); if (result != 0) { throw new Exception(); } string filename = Path.GetFileName(fileName); foreach (string dds in ddsList) { string ddsFile = dds.Split('|')[1]; if (ddsFile.ToLowerInvariant() != filename.ToLowerInvariant()) { continue; } crc = uint.Parse(dds.Split('|')[0].Substring(2), System.Globalization.NumberStyles.HexNumber); break; } if (crc == 0) { if (filename != "texmod.def") { errors += "Skipping file: " + filename + " not founded in texmod.def, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; } ZlibHelper.Zip.GoToNextFile(handle); continue; } List <FoundTexture> foundCrcList = textures.FindAll(s => s.crc == crc); if (foundCrcList.Count == 0) { errors += "Texture skipped. File " + filename + string.Format(" - 0x{0:X8}", crc) + " is not present in your game setup - mod: " + file + Environment.NewLine; ZlibHelper.Zip.GoToNextFile(handle); continue; } string textureName = foundCrcList[0].name; mod.textureName = textureName; mod.binaryMod = false; mod.textureCrc = crc; mod.data = new byte[dstLen]; result = ZlibHelper.Zip.ReadCurrentFile(handle, mod.data, dstLen); if (result != 0) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", crc) + ", skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; ZlibHelper.Zip.GoToNextFile(handle); continue; } uint tag = BitConverter.ToUInt32(mod.data, 0); if (tag != 0x20534444) // DDS { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", crc) + " This texture is not in DDS format, skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; ZlibHelper.Zip.GoToNextFile(handle); continue; } DDSImage image = new DDSImage(new MemoryStream(mod.data)); if (!image.checkExistAllMipmaps()) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", crc) + " This texture has not all the required mipmaps, skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; ZlibHelper.Zip.GoToNextFile(handle); continue; } Package pkg = new Package(GameData.GamePath + foundCrcList[0].list[0].path); Texture texture = new Texture(pkg, foundCrcList[0].list[0].exportID, pkg.getExportData(foundCrcList[0].list[0].exportID)); if (texture.mipMapsList.Count > 1 && image.mipMaps.Count() <= 1) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", crc) + " This texture must have mipmaps, skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; ZlibHelper.Zip.GoToNextFile(handle); continue; } string fmt = texture.properties.getProperty("Format").valueName; DDSFormat ddsFormat = DDSImage.convertFormat(fmt); if (image.ddsFormat != ddsFormat) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", crc) + " This texture has wrong texture format, should be: " + ddsFormat + ", skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; ZlibHelper.Zip.GoToNextFile(handle); continue; } if (image.mipMaps[0].origWidth / image.mipMaps[0].origHeight != texture.mipMapsList[0].width / texture.mipMapsList[0].height) { errors += "Error in texture: " + textureName + string.Format("_0x{0:X8}", crc) + " This texture has wrong aspect ratio, skipping texture, entry: " + (i + 1) + " - mod: " + file + Environment.NewLine; ZlibHelper.Zip.GoToNextFile(handle); continue; } mods.Add(mod); } catch { errors += "Skipping not compatible content, entry: " + (i + 1) + " file: " + fileName + " - mod: " + file + Environment.NewLine; } ZlibHelper.Zip.GoToNextFile(handle); } ZlibHelper.Zip.Close(handle); handle = IntPtr.Zero; } catch { errors += "Mod is not compatible: " + file + Environment.NewLine; if (handle != IntPtr.Zero) { ZlibHelper.Zip.Close(handle); } handle = IntPtr.Zero; continue; } } else if (file.EndsWith(".dds", StringComparison.OrdinalIgnoreCase)) { TexExplorer.BinaryMod mod = new TexExplorer.BinaryMod(); string filename = Path.GetFileNameWithoutExtension(file).ToLowerInvariant(); if (!filename.Contains("0x")) { errors += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (0xhhhhhhhh). Skipping texture..." + Environment.NewLine; continue; } int idx = filename.IndexOf("0x"); if (filename.Length - idx < 10) { errors += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (0xhhhhhhhh). Skipping texture..." + Environment.NewLine; continue; } uint crc; string crcStr = filename.Substring(idx + 2, 8); try { crc = uint.Parse(crcStr, System.Globalization.NumberStyles.HexNumber); } catch { errors += "Texture filename not valid: " + Path.GetFileName(file) + " Texture filename must include texture CRC (0xhhhhhhhh). Skipping texture..." + Environment.NewLine; continue; } List <FoundTexture> foundCrcList = textures.FindAll(s => s.crc == crc); if (foundCrcList.Count == 0) { errors += "Texture skipped. Texture " + Path.GetFileName(file) + " is not present in your game setup." + Environment.NewLine; continue; } using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { mod.data = fs.ReadToBuffer((int)fs.Length); DDSImage image = new DDSImage(new MemoryStream(mod.data)); if (!image.checkExistAllMipmaps()) { errors += "Error in texture: " + Path.GetFileName(file) + " This texture has not all the required mipmaps, skipping texture..." + Environment.NewLine; continue; } Package pkg = new Package(GameData.GamePath + foundCrcList[0].list[0].path); Texture texture = new Texture(pkg, foundCrcList[0].list[0].exportID, pkg.getExportData(foundCrcList[0].list[0].exportID)); if (texture.mipMapsList.Count > 1 && image.mipMaps.Count() <= 1) { errors += "Error in texture: " + Path.GetFileName(file) + " This texture must have mipmaps, skipping texture..." + Environment.NewLine; continue; } string fmt = texture.properties.getProperty("Format").valueName; DDSFormat ddsFormat = DDSImage.convertFormat(fmt); if (image.ddsFormat != ddsFormat) { errors += "Error in texture: " + Path.GetFileName(file) + " This texture has wrong texture format, should be: " + ddsFormat + ", skipping texture..." + Environment.NewLine; continue; } if (image.mipMaps[0].origWidth / image.mipMaps[0].origHeight != texture.mipMapsList[0].width / texture.mipMapsList[0].height) { errors += "Error in texture: " + Path.GetFileName(file) + " This texture has wrong aspect ratio, skipping texture..." + Environment.NewLine; continue; } mod.textureName = foundCrcList[0].name; mod.binaryMod = false; mod.textureCrc = crc; mods.Add(mod); } } } if (mods.Count == 0) { Console.WriteLine("Mods conversion failed"); return(errors); } Console.WriteLine("Saving to MEM file... " + memFilePath); List <MipMaps.FileMod> modFiles = new List <MipMaps.FileMod>(); FileStream outFs; if (File.Exists(memFilePath)) { File.Delete(memFilePath); } using (outFs = new FileStream(memFilePath, FileMode.Create, FileAccess.Write)) { outFs.WriteUInt32(TexExplorer.TextureModTag); outFs.WriteUInt32(TexExplorer.TextureModVersion); outFs.WriteInt64(0); // filled later for (int l = 0; l < mods.Count; l++) { MipMaps.FileMod fileMod = new MipMaps.FileMod(); Stream dst = MipMaps.compressData(mods[l].data); dst.SeekBegin(); fileMod.offset = outFs.Position; fileMod.size = dst.Length; if (mods[l].binaryMod) { fileMod.tag = MipMaps.FileBinaryTag; fileMod.name = Path.GetFileNameWithoutExtension(mods[l].packagePath) + "_" + mods[l].exportId + ".bin"; outFs.WriteInt32(mods[l].exportId); outFs.WriteStringASCIINull(mods[l].packagePath); } else { fileMod.tag = MipMaps.FileTextureTag; fileMod.name = mods[l].textureName + string.Format("_0x{0:X8}", mods[l].textureCrc) + ".dds"; outFs.WriteStringASCIINull(mods[l].textureName); outFs.WriteUInt32(mods[l].textureCrc); } outFs.WriteFromStream(dst, dst.Length); modFiles.Add(fileMod); } long pos = outFs.Position; outFs.SeekBegin(); outFs.WriteUInt32(TexExplorer.TextureModTag); outFs.WriteUInt32(TexExplorer.TextureModVersion); outFs.WriteInt64(pos); outFs.JumpTo(pos); outFs.WriteUInt32((uint)GameData.gameType); outFs.WriteInt32(modFiles.Count); for (int i = 0; i < modFiles.Count; i++) { outFs.WriteUInt32(modFiles[i].tag); outFs.WriteStringASCIINull(modFiles[i].name); outFs.WriteInt64(modFiles[i].offset); outFs.WriteInt64(modFiles[i].size); } } Console.WriteLine("Mods conversion process completed"); return(errors); }
private bool generateBuiltinMapFiles = false; // change to true to enable map files generation public string PrepareListOfTextures(TexExplorer texEplorer, CachePackageMgr cachePackageMgr, MainWindow mainWindow, Installer installer, ref string log, bool force = false) { string errors = ""; treeScan = null; List <FoundTexture> textures = new List <FoundTexture>(); string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Assembly.GetExecutingAssembly().GetName().Name); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string filename = Path.Combine(path, "me" + (int)GameData.gameType + "map.bin"); if (force && File.Exists(filename)) { File.Delete(filename); } if (File.Exists(filename)) { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite)) { uint tag = fs.ReadUInt32(); uint version = fs.ReadUInt32(); if (tag != TexExplorer.textureMapBinTag || version != TexExplorer.textureMapBinVersion) { if (mainWindow != null) { MessageBox.Show("Detected wrong or old version of textures scan file!" + "\n\nYou need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); mainWindow.updateStatusLabel(""); mainWindow.updateStatusLabel2(""); texEplorer.Close(); } fs.Close(); log += "Detected wrong or old version of textures scan file!" + Environment.NewLine; log += "You need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + Environment.NewLine; log += "Then from the main menu, select 'Remove Textures Scan File' and start Texture Manager again." + Environment.NewLine; return("Detected wrong or old version of textures scan file!" + Environment.NewLine + "You need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + Environment.NewLine + "Then from the main menu, select 'Remove Textures Scan File' and start Texture Manager again." + Environment.NewLine); } uint countTexture = fs.ReadUInt32(); for (int i = 0; i < countTexture; i++) { FoundTexture texture = new FoundTexture(); int len = fs.ReadInt32(); texture.name = fs.ReadStringASCII(len); texture.crc = fs.ReadUInt32(); uint countPackages = fs.ReadUInt32(); texture.list = new List <MatchedTexture>(); for (int k = 0; k < countPackages; k++) { MatchedTexture matched = new MatchedTexture(); matched.exportID = fs.ReadInt32(); matched.linkToMaster = fs.ReadInt32(); len = fs.ReadInt32(); matched.path = fs.ReadStringASCII(len); texture.list.Add(matched); } textures.Add(texture); } List <string> packages = new List <string>(); int numPackages = fs.ReadInt32(); for (int i = 0; i < numPackages; i++) { int len = fs.ReadInt32(); string pkgPath = fs.ReadStringASCII(len); pkgPath = GameData.GamePath + pkgPath; packages.Add(pkgPath); } for (int i = 0; i < packages.Count; i++) { if (GameData.packageFiles.Find(s => s.Equals(packages[i], StringComparison.OrdinalIgnoreCase)) == null) { if (mainWindow != null) { MessageBox.Show("Detected removal of game files since last game data scan." + "\n\nYou need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); return(""); } else if (!force) { errors += "Detected removal of game files since last game data scan." + Environment.NewLine + Environment.NewLine + "You need to restore the game to vanilla state then reinstall optional DLC/PCC mods."; return(""); } } } for (int i = 0; i < GameData.packageFiles.Count; i++) { if (packages.Find(s => s.Equals(GameData.packageFiles[i], StringComparison.OrdinalIgnoreCase)) == null) { if (mainWindow != null) { MessageBox.Show("Detected additional game files not present in latest game data scan." + "\n\nYou need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); return(""); } else if (!force) { errors += "Detected additional game files not present in latest game data scan." + Environment.NewLine + Environment.NewLine + "You need to restore the game to vanilla state then reinstall optional DLC/PCC mods."; return(""); } } } treeScan = textures; if (mainWindow != null) { mainWindow.updateStatusLabel(""); mainWindow.updateStatusLabel2(""); } return(errors); } } if (File.Exists(filename)) { File.Delete(filename); } if (mainWindow != null) { List <string> badMods = Misc.detectBrokenMod(GameData.gameType); if (badMods.Count != 0) { errors = ""; for (int l = 0; l < badMods.Count; l++) { errors += badMods[l] + Environment.NewLine; } MessageBox.Show("Detected not compatible mods: \n\n" + errors); return(""); } } if (MipMaps.checkGameDataModded(cachePackageMgr)) { if (mainWindow != null) { MessageBox.Show("Detected modded game. Can not continue." + "\n\nYou need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + "\n\nThen start Texture Manager again."); return(""); } else if (!force) { errors += "Detected modded game. Can not continue." + Environment.NewLine + Environment.NewLine + "You need to restore the game to vanilla state then reinstall optional DLC/PCC mods."; return(""); } } if (mainWindow != null) { DialogResult result = MessageBox.Show("Replacing textures and creating mods requires generating a map of the game's textures.\n" + "You only need to do it once.\n\n" + "IMPORTANT! Your game needs to be in vanilla state and have optional DLC/PCC mods installed.\n\n" + "Are you sure you want to proceed?", "Textures mapping", MessageBoxButtons.YesNo); if (result == DialogResult.No) { texEplorer.Close(); return(""); } } GameData.packageFiles.Sort(); if (mainWindow != null) { Misc.startTimer(); } for (int i = 0; i < GameData.packageFiles.Count; i++) { if (mainWindow != null) { mainWindow.updateStatusLabel("Finding textures in package " + (i + 1) + " of " + GameData.packageFiles.Count + " - " + GameData.packageFiles[i]); } if (installer != null) { installer.updateStatusScan("Scanning textures " + (i * 100 / GameData.packageFiles.Count) + "% "); } errors += FindTextures(textures, GameData.packageFiles[i], cachePackageMgr, ref log); } if (GameData.gameType == MeType.ME1_TYPE) { for (int k = 0; k < textures.Count; k++) { for (int t = 0; t < textures[k].list.Count; t++) { uint mipmapOffset = textures[k].list[t].mipmapOffset; if (textures[k].list[t].slave) { MatchedTexture slaveTexture = textures[k].list[t]; string basePkgName = slaveTexture.basePackageName; if (basePkgName == Path.GetFileNameWithoutExtension(slaveTexture.path).ToUpperInvariant()) { throw new Exception(); } bool found = false; for (int j = 0; j < textures[k].list.Count; j++) { if (!textures[k].list[j].slave && textures[k].list[j].mipmapOffset == mipmapOffset && textures[k].list[j].packageName == basePkgName) { slaveTexture.linkToMaster = j; textures[k].list[t] = slaveTexture; found = true; break; } } if (!found) { log += "Error: not able match 'slave' texture: + " + textures[k].name + " to 'master'."; } } } if (!textures[k].list.Exists(s => s.slave) && textures[k].list.Exists(s => s.weakSlave)) { List <MatchedTexture> texList = new List <MatchedTexture>(); for (int t = 0; t < textures[k].list.Count; t++) { MatchedTexture tex = textures[k].list[t]; if (tex.weakSlave) { texList.Add(tex); } else { texList.Insert(0, tex); } } FoundTexture f = textures[k]; f.list = texList; textures[k] = f; if (textures[k].list[0].weakSlave) { continue; } for (int t = 0; t < textures[k].list.Count; t++) { if (textures[k].list[t].weakSlave) { MatchedTexture slaveTexture = textures[k].list[t]; string basePkgName = slaveTexture.basePackageName; if (basePkgName == Path.GetFileNameWithoutExtension(slaveTexture.path).ToUpperInvariant()) { throw new Exception(); } for (int j = 0; j < textures[k].list.Count; j++) { if (!textures[k].list[j].weakSlave && textures[k].list[j].packageName == basePkgName) { slaveTexture.linkToMaster = j; textures[k].list[t] = slaveTexture; break; } } } } } } } using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) { MemoryStream mem = new MemoryStream(); mem.WriteUInt32(TexExplorer.textureMapBinTag); mem.WriteUInt32(TexExplorer.textureMapBinVersion); mem.WriteInt32(textures.Count); for (int i = 0; i < textures.Count; i++) { mem.WriteInt32(textures[i].name.Length); mem.WriteStringASCII(textures[i].name); mem.WriteUInt32(textures[i].crc); if (generateBuiltinMapFiles) { mem.WriteInt32(textures[i].width); mem.WriteInt32(textures[i].height); mem.WriteInt32((int)textures[i].pixfmt); mem.WriteInt32(textures[i].alphadxt1 ? 1 : 0); mem.WriteInt32(textures[i].numMips); } mem.WriteInt32(textures[i].list.Count); for (int k = 0; k < textures[i].list.Count; k++) { mem.WriteInt32(textures[i].list[k].exportID); mem.WriteInt32(textures[i].list[k].linkToMaster); mem.WriteInt32(textures[i].list[k].path.Length); mem.WriteStringASCII(textures[i].list[k].path); } } if (!generateBuiltinMapFiles) { mem.WriteInt32(GameData.packageFiles.Count); for (int i = 0; i < GameData.packageFiles.Count; i++) { string s = GameData.RelativeGameData(GameData.packageFiles[i]); mem.WriteInt32(s.Length); mem.WriteStringASCII(s); } } mem.SeekBegin(); if (generateBuiltinMapFiles) { fs.WriteUInt32(0x504D5443); fs.WriteUInt32((uint)mem.Length); byte[] compressed = new ZlibHelper.Zlib().Compress(mem.ToArray(), 9); fs.WriteUInt32((uint)compressed.Length); fs.WriteFromBuffer(compressed); } else { fs.WriteFromStream(mem, mem.Length); } } if (mainWindow != null) { if (!generateBuiltinMapFiles) { MipMaps mipmaps = new MipMaps(); if (GameData.gameType == MeType.ME1_TYPE) { errors += mipmaps.removeMipMapsME1(1, textures, null, mainWindow, null); errors += mipmaps.removeMipMapsME1(2, textures, null, mainWindow, null); } else { errors += mipmaps.removeMipMapsME2ME3(textures, null, mainWindow, null); } } var time = Misc.stopTimer(); mainWindow.updateStatusLabel("Done. Process total time: " + Misc.getTimerFormat(time)); mainWindow.updateStatusLabel2(""); } treeScan = textures; return(errors); }
public string PrepareListOfTextures(MeType gameId, TexExplorer texEplorer, MainWindow mainWindow, Installer installer, ref string log, bool ipc) { string errors = ""; treeScan = null; Misc.MD5FileEntry[] md5Entries; if (gameId == MeType.ME1_TYPE) { pkgs = Program.tablePkgsME1; md5Entries = Program.entriesME1; } else if (gameId == MeType.ME2_TYPE) { pkgs = Program.tablePkgsME2; md5Entries = Program.entriesME2; } else { pkgs = Program.tablePkgsME3; md5Entries = Program.entriesME3; } List <FoundTexture> textures = new List <FoundTexture>(); string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Assembly.GetExecutingAssembly().GetName().Name); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string filename = Path.Combine(path, "me" + (int)gameId + "map.bin"); if (mainWindow != null) { if (File.Exists(filename)) { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite)) { uint tag = fs.ReadUInt32(); uint version = fs.ReadUInt32(); if (tag != textureMapBinTag || version != textureMapBinVersion) { MessageBox.Show("Detected wrong or old version of textures scan file!" + "\n\nYou need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); mainWindow.updateStatusLabel(""); mainWindow.updateStatusLabel2(""); texEplorer.Close(); fs.Close(); log += "Detected wrong or old version of textures scan file!" + Environment.NewLine; log += "You need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + Environment.NewLine; log += "Then from the main menu, select 'Remove Textures Scan File' and start Texture Manager again." + Environment.NewLine; return("Detected wrong or old version of textures scan file!" + Environment.NewLine + "You need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + Environment.NewLine + "Then from the main menu, select 'Remove Textures Scan File' and start Texture Manager again." + Environment.NewLine); } uint countTexture = fs.ReadUInt32(); for (int i = 0; i < countTexture; i++) { FoundTexture texture = new FoundTexture(); int len = fs.ReadInt32(); texture.name = fs.ReadStringASCII(len); texture.crc = fs.ReadUInt32(); uint countPackages = fs.ReadUInt32(); texture.list = new List <MatchedTexture>(); for (int k = 0; k < countPackages; k++) { MatchedTexture matched = new MatchedTexture(); matched.exportID = fs.ReadInt32(); matched.linkToMaster = fs.ReadInt32(); len = fs.ReadInt32(); matched.path = fs.ReadStringASCII(len); texture.list.Add(matched); } textures.Add(texture); } List <string> packages = new List <string>(); int numPackages = fs.ReadInt32(); for (int i = 0; i < numPackages; i++) { int len = fs.ReadInt32(); string pkgPath = fs.ReadStringASCII(len); pkgPath = GameData.GamePath + pkgPath; packages.Add(pkgPath); } for (int i = 0; i < packages.Count; i++) { if (GameData.packageFiles.Find(s => s.Equals(packages[i], StringComparison.OrdinalIgnoreCase)) == null) { MessageBox.Show("Detected removal of game files since last game data scan." + "\n\nYou need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); return(""); } } for (int i = 0; i < GameData.packageFiles.Count; i++) { if (packages.Find(s => s.Equals(GameData.packageFiles[i], StringComparison.OrdinalIgnoreCase)) == null) { MessageBox.Show("Detected additional game files not present in latest game data scan." + "\n\nYou need to restore the game to vanilla state then reinstall optional DLC/PCC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); return(""); } } treeScan = textures; mainWindow.updateStatusLabel(""); mainWindow.updateStatusLabel2(""); } if (!texEplorer.verifyGameDataEmptyMipMapsRemoval()) { MessageBox.Show("Detected empty mips in game files." + "\n\nYou need the game in vanilla state and optional DLC/PCC mods." + "\n\nThen from the main menu, select 'Remove Textures Scan File' and start Texture Manager again."); return(""); } return(errors); } if (mainWindow != null) { List <string> badMods = Misc.detectBrokenMod(GameData.gameType); if (badMods.Count != 0) { errors = ""; for (int l = 0; l < badMods.Count; l++) { errors += badMods[l] + Environment.NewLine; } MessageBox.Show("Detected not compatible mods: \n\n" + errors); return(""); } List <string> mods = Misc.detectMods(GameData.gameType); if (mods.Count != 0 && GameData.gameType == MeType.ME1_TYPE && GameData.FullScanME1Game) { errors = ""; for (int l = 0; l < mods.Count; l++) { errors += mods[l] + Environment.NewLine; } DialogResult resp = MessageBox.Show("Detected NOT compatible/supported mods with this version of game: \n\n" + errors + "\n\nPress Cancel to abort or press Ok button to continue.", "Warning !", MessageBoxButtons.OKCancel); if (resp == DialogResult.Cancel) { return(""); } } } DialogResult result = MessageBox.Show("Replacing textures and creating mods requires generating a map of the game's textures.\n" + "You only need to do it once.\n\n" + "IMPORTANT! Your game needs to be in vanilla state and have optional DLC/PCC mods installed.\n\n" + "Are you sure you want to proceed?", "Textures mapping", MessageBoxButtons.YesNo); if (result == DialogResult.No) { texEplorer.Close(); return(""); } Misc.startTimer(); } if (!GameData.FullScanME1Game) { int count = GameData.packageFiles.Count; for (int i = 0; i < count; i++) { if (GameData.packageFiles[i].Contains("_IT.") || GameData.packageFiles[i].Contains("_FR.") || GameData.packageFiles[i].Contains("_ES.") || GameData.packageFiles[i].Contains("_DE.") || GameData.packageFiles[i].Contains("_RA.") || GameData.packageFiles[i].Contains("_RU.") || GameData.packageFiles[i].Contains("_PLPC.") || GameData.packageFiles[i].Contains("_DEU.") || GameData.packageFiles[i].Contains("_FRA.") || GameData.packageFiles[i].Contains("_ITA.") || GameData.packageFiles[i].Contains("_POL.")) { GameData.packageFiles.Add(GameData.packageFiles[i]); GameData.packageFiles.RemoveAt(i--); count--; } } } if (!generateBuiltinMapFiles && !GameData.FullScanME1Game) { List <string> addedFiles = new List <string>(); List <string> modifiedFiles = new List <string>(); loadTexturesMap(gameId, textures); List <string> sortedFiles = new List <string>(); for (int i = 0; i < GameData.packageFiles.Count; i++) { sortedFiles.Add(GameData.RelativeGameData(GameData.packageFiles[i]).ToLowerInvariant()); } sortedFiles.Sort(); for (int k = 0; k < textures.Count; k++) { for (int t = 0; t < textures[k].list.Count; t++) { string pkgPath = textures[k].list[t].path.ToLowerInvariant(); if (sortedFiles.BinarySearch(pkgPath) >= 0) { continue; } MatchedTexture f = textures[k].list[t]; f.path = ""; textures[k].list[t] = f; } } if (installer != null) { installer.updateProgressStatus("Scanning packages"); } if (mainWindow != null) { mainWindow.updateStatusLabel("Scanning packages..."); } if (ipc) { Console.WriteLine("[IPC]STAGE_CONTEXT STAGE_SCAN"); Console.Out.Flush(); } for (int i = 0; i < GameData.packageFiles.Count; i++) { int index = -1; bool modified = true; bool foundPkg = false; string package = GameData.RelativeGameData(GameData.packageFiles[i].ToLowerInvariant()); long packageSize = new FileInfo(GameData.packageFiles[i]).Length; for (int p = 0; p < md5Entries.Length; p++) { if (package == md5Entries[p].path.ToLowerInvariant()) { foundPkg = true; if (packageSize == md5Entries[p].size) { modified = false; break; } index = p; } } if (foundPkg && modified) { modifiedFiles.Add(md5Entries[index].path); } else if (!foundPkg) { addedFiles.Add(GameData.RelativeGameData(GameData.packageFiles[i])); } } int lastProgress = -1; int totalPackages = modifiedFiles.Count + addedFiles.Count; int currentPackage = 0; if (ipc) { Console.WriteLine("[IPC]STAGE_WEIGHT STAGE_SCAN " + string.Format("{0:0.000000}", ((float)totalPackages / GameData.packageFiles.Count))); Console.Out.Flush(); } for (int i = 0; i < modifiedFiles.Count; i++, currentPackage++) { if (installer != null) { installer.updateProgressStatus("Scanning textures " + ((currentPackage + 1) * 100) / totalPackages + "% "); } if (mainWindow != null) { mainWindow.updateStatusLabel("Finding textures in package " + (currentPackage + 1) + " of " + totalPackages + " - " + modifiedFiles[i]); } if (ipc) { Console.WriteLine("[IPC]PROCESSING_FILE " + modifiedFiles[i]); int newProgress = currentPackage * 100 / totalPackages; if (lastProgress != newProgress) { Console.WriteLine("[IPC]TASK_PROGRESS " + newProgress); lastProgress = newProgress; } Console.Out.Flush(); } errors += FindTextures(gameId, textures, modifiedFiles[i], true, ref log); } for (int i = 0; i < addedFiles.Count; i++, currentPackage++) { if (installer != null) { installer.updateProgressStatus("Scanning textures " + ((currentPackage + 1) * 100) / totalPackages + "% "); } if (mainWindow != null) { mainWindow.updateStatusLabel("Finding textures in package " + (currentPackage + 1) + " of " + totalPackages + " - " + addedFiles[i]); } if (ipc) { Console.WriteLine("[IPC]PROCESSING_FILE " + addedFiles[i]); int newProgress = currentPackage * 100 / totalPackages; if (lastProgress != newProgress) { Console.WriteLine("[IPC]TASK_PROGRESS " + newProgress); lastProgress = newProgress; } Console.Out.Flush(); } errors += FindTextures(gameId, textures, addedFiles[i], false, ref log); } for (int k = 0; k < textures.Count; k++) { bool found = false; for (int t = 0; t < textures[k].list.Count; t++) { if (textures[k].list[t].path != "") { found = true; break; } } if (!found) { textures[k].list.Clear(); textures.Remove(textures[k]); k--; } } } else { int lastProgress = -1; for (int i = 0; i < GameData.packageFiles.Count; i++) { if (installer != null) { installer.updateProgressStatus("Scanning textures " + ((i + 1) * 100) / GameData.packageFiles.Count + "% "); } if (mainWindow != null) { mainWindow.updateStatusLabel("Finding textures in package " + (i + 1) + " of " + GameData.packageFiles.Count + " - " + GameData.packageFiles[i]); } if (ipc) { Console.WriteLine("[IPC]PROCESSING_FILE " + GameData.packageFiles[i]); int newProgress = i * 100 / GameData.packageFiles.Count; if (lastProgress != newProgress) { Console.WriteLine("[IPC]TASK_PROGRESS " + newProgress); lastProgress = newProgress; } Console.Out.Flush(); } FindTextures(gameId, textures, GameData.RelativeGameData(GameData.packageFiles[i]), false, ref log); } } if (gameId == MeType.ME1_TYPE) { for (int k = 0; k < textures.Count; k++) { for (int t = 0; t < textures[k].list.Count; t++) { uint mipmapOffset = textures[k].list[t].mipmapOffset; if (textures[k].list[t].slave) { MatchedTexture slaveTexture = textures[k].list[t]; string basePkgName = slaveTexture.basePackageName; if (basePkgName == Path.GetFileNameWithoutExtension(slaveTexture.path).ToUpperInvariant()) { throw new Exception(); } for (int j = 0; j < textures[k].list.Count; j++) { if (!textures[k].list[j].slave && textures[k].list[j].mipmapOffset == mipmapOffset && textures[k].list[j].packageName == basePkgName) { slaveTexture.linkToMaster = j; slaveTexture.slave = true; textures[k].list[t] = slaveTexture; break; } } } } if (!textures[k].list.Exists(s => s.slave) && textures[k].list.Exists(s => s.weakSlave)) { List <MatchedTexture> texList = new List <MatchedTexture>(); for (int t = 0; t < textures[k].list.Count; t++) { MatchedTexture tex = textures[k].list[t]; if (tex.weakSlave) { texList.Add(tex); } else { texList.Insert(0, tex); } } FoundTexture f = textures[k]; f.list = texList; textures[k] = f; if (textures[k].list[0].weakSlave) { continue; } for (int t = 0; t < textures[k].list.Count; t++) { if (textures[k].list[t].weakSlave) { MatchedTexture slaveTexture = textures[k].list[t]; string basePkgName = slaveTexture.basePackageName; if (basePkgName == Path.GetFileNameWithoutExtension(slaveTexture.path).ToUpperInvariant()) { throw new Exception(); } for (int j = 0; j < textures[k].list.Count; j++) { if (!textures[k].list[j].weakSlave && textures[k].list[j].packageName == basePkgName) { slaveTexture.linkToMaster = j; slaveTexture.slave = true; textures[k].list[t] = slaveTexture; break; } } } } } } } if (File.Exists(filename)) { File.Delete(filename); } using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) { MemoryStream mem = new MemoryStream(); mem.WriteUInt32(textureMapBinTag); mem.WriteUInt32(textureMapBinVersion); mem.WriteInt32(textures.Count); for (int i = 0; i < textures.Count; i++) { if (generateBuiltinMapFiles) { mem.WriteByte((byte)textures[i].name.Length); } else { mem.WriteInt32(textures[i].name.Length); } mem.WriteStringASCII(textures[i].name); mem.WriteUInt32(textures[i].crc); if (generateBuiltinMapFiles) { mem.WriteInt16((short)textures[i].width); mem.WriteInt16((short)textures[i].height); mem.WriteByte((byte)textures[i].pixfmt); mem.WriteByte((byte)textures[i].flags); mem.WriteInt16((short)textures[i].list.Count); } else { mem.WriteInt32(textures[i].list.Count); } for (int k = 0; k < textures[i].list.Count; k++) { mem.WriteInt32(textures[i].list[k].exportID); if (generateBuiltinMapFiles) { if (GameData.gameType == MeType.ME1_TYPE) { mem.WriteInt16((short)textures[i].list[k].linkToMaster); if (textures[i].list[k].linkToMaster != -1) { mem.WriteStringASCIINull(textures[i].list[k].basePackageName); } } mem.WriteByte(textures[i].list[k].removeEmptyMips ? (byte)1 : (byte)0); mem.WriteByte((byte)textures[i].list[k].numMips); mem.WriteInt16((short)pkgs.IndexOf(textures[i].list[k].path)); } else { mem.WriteInt32(textures[i].list[k].linkToMaster); mem.WriteInt32(textures[i].list[k].path.Length); mem.WriteStringASCII(textures[i].list[k].path); } } } if (!generateBuiltinMapFiles) { mem.WriteInt32(GameData.packageFiles.Count); for (int i = 0; i < GameData.packageFiles.Count; i++) { string s = GameData.RelativeGameData(GameData.packageFiles[i]); mem.WriteInt32(s.Length); mem.WriteStringASCII(s); } } mem.SeekBegin(); if (generateBuiltinMapFiles) { fs.WriteUInt32(0x504D5443); fs.WriteUInt32((uint)mem.Length); byte[] compressed = new ZlibHelper.Zlib().Compress(mem.ToArray(), 9); fs.WriteUInt32((uint)compressed.Length); fs.WriteFromBuffer(compressed); } else { fs.WriteFromStream(mem, mem.Length); } } if (mainWindow != null) { if (!generateBuiltinMapFiles) { MipMaps mipmaps = new MipMaps(); if (GameData.gameType == MeType.ME1_TYPE) { errors += mipmaps.removeMipMapsME1(1, textures, mainWindow, null, false); errors += mipmaps.removeMipMapsME1(2, textures, mainWindow, null, false); } else { errors += mipmaps.removeMipMapsME2ME3(textures, mainWindow, null, false, false); } if (GameData.gameType == MeType.ME3_TYPE) { TOCBinFile.UpdateAllTOCBinFiles(); } } } treeScan = textures; if (mainWindow != null) { var time = Misc.stopTimer(); mainWindow.updateStatusLabel("Done. Process total time: " + Misc.getTimerFormat(time)); mainWindow.updateStatusLabel2(""); } return(errors); }
void toolStripCreateBinaryMod(MeType gameType) { enableGameDataMenu(false); GameData gameData = new GameData(gameType, _configIni); if (!Directory.Exists(GameData.GamePath)) { MessageBox.Show("Game path is wrong!"); enableGameDataMenu(true); return; } updateStatusLabel("Finding packages in game setup..."); gameData.getPackages(); updateStatusLabel(""); using (FolderBrowserDialog modDir = new FolderBrowserDialog()) { modDir.Description = "Please select source directory of modded package files"; if (modDir.ShowDialog() != DialogResult.OK) { updateStatusLabel(""); enableGameDataMenu(true); return; } List <string> exe = Directory.GetFiles(modDir.SelectedPath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)).ToList(); if (exe.Count != 0) { MessageBox.Show("The source directory doesn't seems right, aborting..."); updateStatusLabel(""); enableGameDataMenu(true); return; } List <string> mods = Directory.GetFiles(modDir.SelectedPath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".upk", StringComparison.OrdinalIgnoreCase) || s.EndsWith(".u", StringComparison.OrdinalIgnoreCase) || s.EndsWith(".pcc", StringComparison.OrdinalIgnoreCase) || s.EndsWith(".sfm", StringComparison.OrdinalIgnoreCase)).ToList(); for (int i = 0; i < mods.Count; i++) { try { using (FileStream fs = new FileStream(mods[i], FileMode.Open, FileAccess.Read)) { fs.SeekEnd(); fs.Seek(-Package.MEMendFileMarker.Length, SeekOrigin.Current); string marker = fs.ReadStringASCII(Package.MEMendFileMarker.Length); if (marker == Package.MEMendFileMarker) { MessageBox.Show("Mod files must be based on vanilla game data, aborting..."); updateStatusLabel(""); enableGameDataMenu(true); return; } } } catch { } } updateStatusLabel("Scanning mods..."); List <string> files = Directory.GetFiles(modDir.SelectedPath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".upk", StringComparison.OrdinalIgnoreCase) || s.EndsWith(".u", StringComparison.OrdinalIgnoreCase) || s.EndsWith(".pcc", StringComparison.OrdinalIgnoreCase) || s.EndsWith(".sfm", StringComparison.OrdinalIgnoreCase)).ToList(); List <BinaryMod> modFiles = new List <BinaryMod>(); for (int i = 0; i < mods.Count; i++) { Package vanillaPkg = null; Package modPkg = null; bool found = false; try { for (int v = 0; v < GameData.packageFiles.Count; v++) { if (Path.GetFileName(mods[i]).ToLowerInvariant() == Path.GetFileName(GameData.packageFiles[v]).ToLowerInvariant()) { modPkg = new Package(mods[i]); vanillaPkg = new Package(GameData.packageFiles[v]); if (modPkg.exportsTable.Count != vanillaPkg.exportsTable.Count || modPkg.namesTable.Count != vanillaPkg.namesTable.Count || modPkg.importsTable.Count != vanillaPkg.importsTable.Count) { found = true; vanillaPkg.Dispose(); vanillaPkg = null; continue; } found = true; break; } } if (found && vanillaPkg == null) { modPkg.Dispose(); MessageBox.Show("Package file not compatible: " + mods[i] + ", aborting..."); updateStatusLabel(""); enableGameDataMenu(true); return; } } catch { MessageBox.Show("Problem opening file: " + mods[i] + ", aborting..."); updateStatusLabel(""); enableGameDataMenu(true); return; } if (!found) { MessageBox.Show("Package not present in vanilla game data: " + mods[i] + ", aborting..."); updateStatusLabel(""); enableGameDataMenu(true); return; } for (int e = 0; e < modPkg.exportsTable.Count; e++) { byte[] vanillaExport = vanillaPkg.getExportData(e); byte[] modExport = modPkg.getExportData(e); if (vanillaExport.Length == modExport.Length) { if (StructuralComparisons.StructuralEqualityComparer.Equals(vanillaExport, modExport)) { continue; } } BinaryMod mod = new BinaryMod(); mod.packagePath = GameData.RelativeGameData(vanillaPkg.packagePath); mod.exportId = e; if (vanillaExport.Length == modExport.Length) { mod.data = new Xdelta3Helper.Xdelta3().Compress(vanillaExport, modExport); mod.binaryModType = 2; } else { mod.data = new byte[modExport.Length]; Array.Copy(modExport, mod.data, modExport.Length); mod.binaryModType = 1; } string name; if (mod.packagePath.Contains("\\DLC\\")) { string dlcName = mod.packagePath.Split('\\')[3]; name = "D" + dlcName.Length + "-" + dlcName + "-"; } else { name = "B"; } name += Path.GetFileName(mod.packagePath).Length + "-" + Path.GetFileName(mod.packagePath) + "-E" + mod.exportId; if (mod.binaryModType == 1) { name += ".bin"; } else if (mod.binaryModType == 2) { name += ".xdelta"; } mod.textureName = name; modFiles.Add(mod); } vanillaPkg.Dispose(); modPkg.Dispose(); } if (modFiles.Count == 0) { MessageBox.Show("Nothing to mod, exiting..."); updateStatusLabel(""); enableGameDataMenu(true); return; } updateStatusLabel("Creating mem..."); using (SaveFileDialog modFile = new SaveFileDialog()) { modFile.Title = "Please selecct new MEM mod file"; modFile.Filter = "MEM mod file | *.mem"; if (modFile.ShowDialog() != DialogResult.OK) { updateStatusLabel(""); enableGameDataMenu(true); return; } if (File.Exists(modFile.FileName)) { File.Delete(modFile.FileName); } using (FileStream outFs = new FileStream(modFile.FileName, FileMode.CreateNew, FileAccess.Write)) { outFs.WriteUInt32(TreeScan.TextureModTag); outFs.WriteUInt32(TreeScan.TextureModVersion); outFs.WriteInt64(0); // filled later for (int i = 0; i < modFiles.Count; i++) { Stream dst = MipMaps.compressData(modFiles[i].data); dst.SeekBegin(); BinaryMod bmod = modFiles[i]; bmod.offset = outFs.Position; bmod.size = dst.Length; modFiles[i] = bmod; outFs.WriteInt32(modFiles[i].exportId); outFs.WriteStringASCIINull(modFiles[i].packagePath); outFs.WriteFromStream(dst, dst.Length); } long pos = outFs.Position; outFs.SeekBegin(); outFs.WriteUInt32(TreeScan.TextureModTag); outFs.WriteUInt32(TreeScan.TextureModVersion); outFs.WriteInt64(pos); outFs.JumpTo(pos); outFs.WriteUInt32((uint)gameType); outFs.WriteInt32(modFiles.Count); for (int i = 0; i < modFiles.Count; i++) { if (modFiles[i].binaryModType == 1) { outFs.WriteUInt32(MipMaps.FileBinaryTag); } else if (modFiles[i].binaryModType == 2) { outFs.WriteUInt32(MipMaps.FileXdeltaTag); } outFs.WriteStringASCIINull(modFiles[i].textureName); outFs.WriteInt64(modFiles[i].offset); outFs.WriteInt64(modFiles[i].size); } } } } updateStatusLabel("Finished"); enableGameDataMenu(true); }
public void applyModules() { for (int i = 0; i < memFiles.Count; i++) { log += "Mod: " + (i + 1) + " of " + memFiles.Count + " started: " + Path.GetFileName(memFiles[i]) + Environment.NewLine; using (FileStream fs = new FileStream(memFiles[i], FileMode.Open, FileAccess.Read)) { uint tag = fs.ReadUInt32(); uint version = fs.ReadUInt32(); if (tag != TexExplorer.TextureModTag || version != TexExplorer.TextureModVersion) { if (version != TexExplorer.TextureModVersion) { errors += "File " + memFiles[i] + " was made with an older version of MEM, skipping..." + Environment.NewLine; log += "File " + memFiles[i] + " was made with an older version of MEM, skipping..." + Environment.NewLine; } else { errors += "File " + memFiles[i] + " is not a valid MEM mod, skipping..." + Environment.NewLine; log += "File " + memFiles[i] + " is not a valid MEM mod, skipping..." + Environment.NewLine; } continue; } else { uint gameType = 0; fs.JumpTo(fs.ReadInt64()); gameType = fs.ReadUInt32(); if ((MeType)gameType != GameData.gameType) { errors += "File " + memFiles[i] + " is not a MEM mod valid for this game, skipping..." + Environment.NewLine; log += "File " + memFiles[i] + " is not a MEM mod valid for this game, skipping..." + Environment.NewLine; continue; } } int numFiles = fs.ReadInt32(); List <MipMaps.FileMod> modFiles = new List <MipMaps.FileMod>(); for (int k = 0; k < numFiles; k++) { MipMaps.FileMod fileMod = new MipMaps.FileMod(); fileMod.tag = fs.ReadUInt32(); fileMod.name = fs.ReadStringASCIINull(); fileMod.offset = fs.ReadInt64(); fileMod.size = fs.ReadInt64(); modFiles.Add(fileMod); } numFiles = modFiles.Count; for (int l = 0; l < numFiles; l++) { string name = ""; uint crc = 0; long size = 0, dstLen = 0; int exportId = -1; string pkgPath = ""; byte[] dst = null; fs.JumpTo(modFiles[l].offset); size = modFiles[l].size; if (modFiles[l].tag == MipMaps.FileTextureTag) { name = fs.ReadStringASCIINull(); crc = fs.ReadUInt32(); } else if (modFiles[l].tag == MipMaps.FileBinaryTag) { name = modFiles[l].name; exportId = fs.ReadInt32(); pkgPath = fs.ReadStringASCIINull(); } dst = MipMaps.decompressData(fs, size); dstLen = dst.Length; updateStatusTextures("Mod: " + (i + 1) + " of " + memFiles.Count + " - in progress: " + ((l + 1) * 100 / numFiles) + " % "); if (modFiles[l].tag == MipMaps.FileTextureTag) { FoundTexture foundTexture; foundTexture = textures.Find(s => s.crc == crc); if (foundTexture.crc != 0) { DDSImage image = new DDSImage(new MemoryStream(dst, 0, (int)dstLen)); if (!image.checkExistAllMipmaps()) { errors += "Error in texture: " + name + string.Format("_0x{0:X8}", crc) + " Texture skipped. This texture has not all the required mipmaps" + Environment.NewLine; log += "Error in texture: " + name + string.Format("_0x{0:X8}", crc) + " Texture skipped. This texture has not all the required mipmaps" + Environment.NewLine; continue; } errors += mipMaps.replaceTexture(image, foundTexture.list, cachePackageMgr, foundTexture.name, crc); } else { log += "Texture skipped. Texture " + name + string.Format("_0x{0:X8}", crc) + " is not present in your game setup" + Environment.NewLine; } } else if (modFiles[l].tag == MipMaps.FileBinaryTag) { string path = GameData.GamePath + pkgPath; if (!File.Exists(path)) { log += "Warning: File " + path + " not exists in your game setup." + Environment.NewLine; continue; } Package pkg = cachePackageMgr.OpenPackage(path); pkg.setExportData(exportId, dst); } else { errors += "Unknown tag for file: " + name + Environment.NewLine; log += "Unknown tag for file: " + name + Environment.NewLine; } } } } }