public static void CreateUnpackedTOC(string dlcDirectory) { Log.Information(@"Creating unpacked toc for " + dlcDirectory); //#if DEBUG // if (dlcDirectory.Contains(@"DLC_CON_END") || dlcDirectory.Contains(@"DLC_EXP_Pack002")) // { // Debugger.Break(); // throw new Exception(@"ASSERT ERROR: CREATING UNPACKED TOC FOR OFFICIAL DLC!"); // } //#endif var watch = System.Diagnostics.Stopwatch.StartNew(); MemoryStream ms = TOCCreator.CreateTOCForDirectory(dlcDirectory); if (ms != null) { string tocPath = Path.Combine(dlcDirectory, @"PCConsoleTOC.bin"); File.WriteAllBytes(tocPath, ms.ToArray()); ms.Close(); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; Log.Information($@"{Path.GetFileName(dlcDirectory)} - {dlcDirectory} Ran Unpacked TOC, took {elapsedMs}ms"); } else { Log.Warning(@"Did not create TOC for " + dlcDirectory); watch.Stop(); } }
private void CreateUnpackedTOC(string dlcDirectory) { var watch = System.Diagnostics.Stopwatch.StartNew(); MemoryStream ms = TOCCreator.CreateTOCForDirectory(dlcDirectory); if (ms != null) { string tocPath = Path.Combine(dlcDirectory, "PCConsoleTOC.bin"); File.WriteAllBytes(tocPath, ms.ToArray()); ms.Close(); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; Log.Information($"{Path.GetFileName(dlcDirectory)} - {dlcDirectory} Ran Unpacked TOC, took {elapsedMs}ms"); } else { Log.Warning("Did not create TOC for " + dlcDirectory); watch.Stop(); } }
public DLCTOCUpdateResult UpdateTOCbin(bool rebuildSFAR = false) { int archiveFileIndex = -1; for (int i = 0; i < Files.Length; i++) { if (Path.GetFileName(Files[i].FileName) == @"PCConsoleTOC.bin") { archiveFileIndex = i; break; } } if (archiveFileIndex == -1) { Debug.WriteLine(@"Couldn't find PCConsoleTOC.bin in SFAR"); return(DLCTOCUpdateResult.RESULT_ERROR_NO_TOC); } //Collect list of information from the SFAR Header of files and their sizes var entries = new List <(string filepath, int size)>(); foreach (var file in Files) { if (file.FileName != UNKNOWN_FILENAME) { string consoleDirFilename = file.FileName.Substring(file.FileName.IndexOf(@"DLC_", StringComparison.InvariantCultureIgnoreCase)); consoleDirFilename = consoleDirFilename.Substring(consoleDirFilename.IndexOf('/') + 1); entries.Add((consoleDirFilename.Replace('/', '\\'), (int)file.UncompressedSize)); } } //Substring out the dlc name //Read the current TOC and see if an update is necessary. bool tocNeedsUpdating = false; var tocMemoryStream = DecompressEntry(archiveFileIndex); TOCBinFile toc = new TOCBinFile(tocMemoryStream); int actualTocEntries = toc.Entries.Count; actualTocEntries -= toc.Entries.Count(x => x.name.EndsWith(@"PCConsoleTOC.txt", StringComparison.InvariantCultureIgnoreCase)); actualTocEntries -= toc.Entries.Count(x => x.name.EndsWith(@"GlobalPersistentCookerData.upk", StringComparison.InvariantCultureIgnoreCase)); if (actualTocEntries != entries.Count) { tocNeedsUpdating = true; } else { //Check sizes to see if all of ours match. foreach (var entry in toc.Entries) { if (entry.name.EndsWith(@"PCConsoleTOC.txt", StringComparison.InvariantCultureIgnoreCase) || entry.name.EndsWith("GlobalPersistentCookerData.upk", StringComparison.InvariantCultureIgnoreCase)) { continue; //These files don't actually exist in SFARs } var matchingNewEntry = entries.FirstOrDefault(x => x.filepath.Equals(entry.name, StringComparison.InvariantCultureIgnoreCase)); if (matchingNewEntry.filepath == null) { //same number of files but we could not find it in the list. A delete and add might have caused this. tocNeedsUpdating = true; break; } if (matchingNewEntry.size != entry.size) { //size is different. tocNeedsUpdating = true; break; } } } //DEBUG TESTING! if (tocNeedsUpdating || FileName.Contains(@"Patch_001")) { MemoryStream newTocStream = TOCCreator.CreateTOCForEntries(entries); byte[] newmem = newTocStream.ToArray(); //if (tocMemoryStream.ToArray().SequenceEqual(newTocStream.ToArray())) //{ // //no update needed // return DLCTOCUpdateResult.RESULT_UPDATE_NOT_NECESSARY; //} ReplaceEntry(newmem, archiveFileIndex); } else { return(DLCTOCUpdateResult.RESULT_UPDATE_NOT_NECESSARY); // no update needed } //int IndexTOC = archiveFileIndex; //byte[] originalTOCBinary = tocMemoryStream.ToArray(); //TOCBinFile TOC = new TOCBinFile(tocMemoryStream); //int count = 0; //if (TOC.Entries == null) //{ // Debug.WriteLine("No TOC entries found!"); // return null; //} //for (int i = 0; i < TOC.Entries.Count; i++) //{ // TOCBinFile.Entry e = TOC.Entries[i]; // archiveFileIndex = -1; // //Find file in archive that this TOC entry is for // for (int fileIndex = 0; fileIndex < Files.Length; fileIndex++) // { // if (Files[fileIndex].FileName.Replace('/', '\\').Contains(e.name)) // { // archiveFileIndex = fileIndex; // break; // } // } // if (archiveFileIndex == -1) // { // //Not in the archive/ // List<string> parts = new List<string>(this.FileName.Split('\\')); // parts.RemoveAt(parts.Count - 1); // parts.RemoveAt(parts.Count - 1); // string path = string.Join("\\", parts) + "\\" + e.name; // if (File.Exists(path)) // { // FileInfo fi = new FileInfo(path); // if (fi.Length != e.size) // { // e.size = (int)fi.Length; // TOC.Entries[i] = e; // } // } // else // Debug.WriteLine("Entry not found: " + e.name); // } // else // { // if (Files[archiveFileIndex].UncompressedSize != e.size) // { // e.size = (int)Files[archiveFileIndex].UncompressedSize; // TOC.Entries[i] = e; // } // } //} //ReplaceEntry(TOC.Save().ToArray(), IndexTOC); if (rebuildSFAR) { Load(FileName); ReBuild(); } return(DLCTOCUpdateResult.RESULT_UPDATED); }
public static bool RunTOCOnGameTarget(GameTarget target, Action <int> percentDoneCallback = null) { Log.Information(@"Autotocing game: " + target.TargetPath); //if (target.Game.IsLEGame()) //{ TOCCreator.CreateTOCForGame(target.Game, percentDoneCallback, target.TargetPath); return(true); //} /* * //get toc target folders, ensuring we clean up the inputs a bit. * string baseDir = Path.GetFullPath(Path.Combine(target.TargetPath, @"BIOGame")); * string dlcDirRoot = M3Directories.GetDLCPath(target); * if (!Directory.Exists(dlcDirRoot)) * { * Log.Error(@"Specified game directory does not appear to be a Mass Effect 3 root game directory (DLC folder missing)."); * return false; * } * * var tocTargets = (new DirectoryInfo(dlcDirRoot)).GetDirectories().Select(x => x.FullName).Where(x => Path.GetFileName(x).StartsWith(@"DLC_", StringComparison.OrdinalIgnoreCase)).ToList(); * tocTargets.Add(baseDir); * tocTargets.Add(Path.Combine(target.TargetPath, @"BIOGame\Patches\PCConsole\Patch_001.sfar")); * * //Debug.WriteLine("Found TOC Targets:"); * //tocTargets.ForEach(x => Debug.WriteLine(x)); * //Debug.WriteLine("=====Generating TOC Files====="); * int done = 0; * * foreach (var tocTarget in tocTargets) * { * string sfar = Path.Combine(tocTarget, SFAR_SUBPATH); * if (tocTarget.EndsWith(@".sfar")) * { * //TestPatch * var watch = Stopwatch.StartNew(); * DLCPackage dlc = new DLCPackage(tocTarget); * var tocResult = dlc.UpdateTOCbin(); * watch.Stop(); * if (tocResult == DLCPackage.DLCTOCUpdateResult.RESULT_UPDATE_NOT_NECESSARY) * { * Log.Information($@"TOC is already up to date in {tocTarget}"); * } * else if (tocResult == DLCPackage.DLCTOCUpdateResult.RESULT_UPDATED) * { * var elapsedMs = watch.ElapsedMilliseconds; * Log.Information($@"{tocTarget} - Ran SFAR TOC, took {elapsedMs}ms"); * } * } * else if (ME3Directory.OfficialDLCNames.ContainsKey(Path.GetFileName(tocTarget))) * { * //Official DLC * if (File.Exists(sfar)) * { * if (new FileInfo(sfar).Length == 32) //DLC is unpacked for sure * { * CreateUnpackedTOC(tocTarget); * } * else * { * //AutoTOC it - SFAR is not unpacked * var watch = System.Diagnostics.Stopwatch.StartNew(); * * DLCPackage dlc = new DLCPackage(sfar); * var tocResult = dlc.UpdateTOCbin(); * watch.Stop(); * if (tocResult == DLCPackage.DLCTOCUpdateResult.RESULT_ERROR_NO_ENTRIES) * { * Log.Information($@"No DLC entries in SFAR... Suspicious. Creating empty TOC for {tocTarget}"); * CreateUnpackedTOC(tocTarget); * } * else if (tocResult == DLCPackage.DLCTOCUpdateResult.RESULT_UPDATE_NOT_NECESSARY) * { * Log.Information($@"TOC is already up to date in {tocTarget}"); * } * else if (tocResult == DLCPackage.DLCTOCUpdateResult.RESULT_UPDATED) * { * var elapsedMs = watch.ElapsedMilliseconds; * Log.Information($@"{Path.GetFileName(tocTarget)} - Ran SFAR TOC, took {elapsedMs}ms"); * } * } * } * * } * else * { * //TOC it unpacked style * // Console.WriteLine(foldername + ", - UNPACKED TOC"); * CreateUnpackedTOC(tocTarget); * } * * done++; * percentDoneCallback?.Invoke((int)Math.Floor(done * 100.0 / tocTargets.Count)); * } * return true;*/ }