public void Save(string directory) { IndexContainer?.Save(directory, ConfigContainer); RootFile?.Write(directory, this); DownloadFile?.Write(directory, this); DownloadSizeFile?.Write(directory, this); InstallFile?.Write(directory, this); EncodingFile?.Write(directory, ConfigContainer); ConfigContainer?.Save(directory); RootFile?.FileLookup?.Close(); }
public void LoadProject(string fileName) { if (!File.Exists(fileName)) { MessageBox.Show("The specified file does not exist"); return; } ClearDebug(null); ProgressDialog.ShowModal(() => Project.Load(fileName)); RootFile.Clear(); RootFile.Add(Project.RootWidget); }
public ProductHandler_D2R(ClientHandler client, Stream stream) { m_client = client; using (BinaryReader reader = new BinaryReader(stream)) { string str = Encoding.ASCII.GetString(reader.ReadBytes((int)stream.Length)); string[] array = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); m_rootFiles = new RootFile[array.Length - 1]; for (var i = 1; i < array.Length; i++) { m_rootFiles[i - 1] = new RootFile(array[i].Split('|')[0], array[i].Split('|')[1]); } } }
public void Save(string directory) { // if this field exists and mismatches the generated file; the client will error // if this field is missing the client will generate the file and variable itself ConfigContainer?.CDNConfig?.GetValues("archive-group")?.Clear(); IndexContainer?.Save(directory, ConfigContainer); RootFile?.Write(directory, this); DownloadFile?.Write(directory, this); DownloadSizeFile?.Write(directory, this); InstallFile?.Write(directory, this); EncodingFile?.Write(directory, ConfigContainer); ConfigContainer?.Save(directory); RootFile?.FileLookup?.Close(); }
/// <summary> /// Retrieve the list of base directories for native projects /// </summary> public static IEnumerable <DirectoryReference> EnumerateBaseDirectories() { if (CachedBaseDirectories == null) { lock (LockObject) { if (CachedBaseDirectories == null) { HashSet <DirectoryReference> BaseDirs = new HashSet <DirectoryReference>(); foreach (FileReference RootFile in DirectoryLookupCache.EnumerateFiles(UnrealBuildTool.RootDirectory)) { if (RootFile.HasExtension(".uprojectdirs")) { foreach (string Line in File.ReadAllLines(RootFile.FullName)) { string TrimLine = Line.Trim(); if (!TrimLine.StartsWith(";")) { DirectoryReference BaseProjectDir = DirectoryReference.Combine(UnrealBuildTool.RootDirectory, TrimLine); if (BaseProjectDir.IsUnderDirectory(UnrealBuildTool.RootDirectory)) { BaseDirs.Add(BaseProjectDir); } else { Log.TraceWarning("Project search path '{0}' referenced by '{1}' is not under '{2}', ignoring.", TrimLine, RootFile, UnrealBuildTool.RootDirectory); } } } } } CachedBaseDirectories = BaseDirs; } } } return(CachedBaseDirectories); }
public void TestCKeys() { // WOW-28807patch8.1.0_PTR string ckey = "0105f03cb8b8faceda8ea099c2f2f476"; Indices.IndexFile index = new Indices.IndexFile(Path.Combine(PATH, @"data\01\05", "0105f03cb8b8faceda8ea099c2f2f476.index")); index.Write("test"); Assert.AreEqual(ckey, index.Checksum.ToString()); //ckey = "1228b5ef225fa4b85eebc5e32b1ca238"; //RootFile rootFile = new RootFile(PATH, new MD5Hash("fc52ef45efbbc6beca39076f89bad99f")); //Assert.AreEqual(ckey, rootFile.Write(@"test").CKey.ToString()); ckey = "1de5b9ebaa9c117f0c2d5430f8b296d4"; RootFile rootFileV2 = new RootFile(PATH, new MD5Hash("923b2669b887c65b2271405ce51a052b")); Assert.AreEqual(ckey, rootFileV2.Write("test").CKey.ToString()); ckey = "9faeafadd4ee3fa03de41eb2360e7f46"; EncodingFile encodingFile = new EncodingFile(PATH, new MD5Hash("c08602c3fe517a2a2eec27f6cffbb627")); Assert.AreEqual(ckey, encodingFile.Write("test").CKey.ToString()); ckey = "22c7766aae84c1efb081c458d43a5bc7"; Install.InstallFile installFile = new Install.InstallFile(PATH, new MD5Hash("c6ebc4d0b75f279b7d8259715d76107a")); Assert.AreEqual(ckey, installFile.Write("test").CKey.ToString()); ckey = "21f3d8cf8c1e49ce90aa81cec19eef89"; Download.DownloadFile downloadFile = new Download.DownloadFile(PATH, new MD5Hash("b8e459cff125e452e404714d29bc20e3")); downloadFile.DownloadHeader.IncludeChecksum = true; Assert.AreEqual(ckey, downloadFile.Write("test").CKey.ToString()); ckey = "a934b6684ac4fd35a9cde796fc5d3f25"; Download.DownloadSizeFile downloadSizeFile = new Download.DownloadSizeFile(PATH, new MD5Hash("001cc5c73390ac2f5882d65edea4751b")); Assert.AreEqual(ckey, downloadSizeFile.Write("test").CKey.ToString()); }
public ProductHandler_Tank(ClientHandler client, Stream stream) { m_client = client; var clientArgs = client.CreateArgs.HandlerArgs as ClientCreateArgs_Tank ?? new ClientCreateArgs_Tank(); using (BinaryReader reader = new BinaryReader(stream)) { string str = Encoding.ASCII.GetString(reader.ReadBytes((int)stream.Length)); string[] array = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); if (ROOT_FILE_FIELD_ORDER_CHECK != array[0]) { throw new InvalidDataException($"ProductHandler_Tank: Root file field list mismatch ({array[0]})"); } m_rootFiles = new RootFile[array.Length - 1]; for (int i = 1; i < array.Length; i++) { m_rootFiles[i - 1] = new RootFile(array[i].Split('|')); } } if (!clientArgs.LoadManifest) { return; } int totalAssetCount = 0; foreach (RootFile rootFile in m_rootFiles.Reverse()) // cmf first, then apm { string extension = Path.GetExtension(rootFile.FileName); if (extension != ".cmf" && extension != ".apm" && extension != ".trg") { continue; } var manifestName = Path.GetFileNameWithoutExtension(rootFile.FileName); var manifestFileName = Path.GetFileName(rootFile.FileName); if (!manifestName.Contains(clientArgs.ManifestRegion ?? REGION_DEV)) { continue; // is a CN (china) CMF. todo: support this } var locale = GetManifestLocale(manifestName); // ReSharper disable once ConvertIfStatementToSwitchStatement if (extension == ".cmf") { bool speech = manifestName.Contains(SPEECH_MANIFEST_NAME); bool text = manifestName.Contains(TEXT_MANIFEST_NAME); if (speech) { if (locale != client.CreateArgs.SpeechLanguage) { continue; } } else if (locale != null) { // text or old root/text combo if (locale != client.CreateArgs.TextLanguage) { continue; } } ContentManifestFile cmf; //using (Stream file = File.OpenWrite($"{manifestName}.cmf")) { // cmfStream.CopyTo(file); //} try { using (Stream cmfStream = client.OpenCKey(rootFile.MD5)) cmf = new ContentManifestFile(client, cmfStream, manifestFileName); } catch (CryptographicException) { Logger.Error("CASC", OutdatedTACTLibErrorMessage); if (Debugger.IsAttached) { Debugger.Break(); } throw; } if (speech) { m_speechContentManifest = cmf; } else if (text) { m_textContentManifest = cmf; } else { m_rootContentManifest = cmf; } totalAssetCount += cmf.m_header.m_dataCount; } else if (extension == ".apm") { if (locale != client.CreateArgs.TextLanguage) { continue; } using (Stream apmStream = client.OpenCKey(rootFile.MD5)) m_packageManifest = new ApplicationPackageManifest(client, this, apmStream, manifestName); } else if (extension == ".trg") { try { using (Stream trgStream = client.OpenCKey(rootFile.MD5)) { //using (Stream file = File.OpenWrite($"{manifestName}.trg")) { // trgStream.CopyTo(file); //} m_resourceGraph = new ResourceGraph(client, trgStream, manifestFileName); } } catch (CryptographicException) { Logger.Error("CASC", OutdatedTACTLibErrorMessage); if (Debugger.IsAttached) { Debugger.Break(); } throw; } } } m_usingResourceGraph = m_rootContentManifest.m_header.m_buildVersion >= VERSION_148_PTR; m_assets = new ConcurrentDictionary <ulong, Asset>(Environment.ProcessorCount + 2, totalAssetCount); if (!m_usingResourceGraph) { for (int i = 0; i < m_packageManifest.m_header.m_packageCount; i++) { var records = m_packageManifest.m_packageRecords[i]; for (int j = 0; j < records.Length; j++) { var record = records[j]; //Console.Out.WriteLine($"{record.GUID:X8} {record.Unknown1} {record.Unknown2} {Manifests[0].ContentManifest.Exists(record.GUID)} {Manifests[1].ContentManifest.Exists(record.GUID)}"); if (m_assets.ContainsKey(record.m_GUID)) { continue; } m_assets[record.m_GUID] = new Asset(i, j); } } } RegisterCMFAssets(m_rootContentManifest, PACKAGE_IDX_FAKE_ROOT_CMF); RegisterCMFAssets(m_textContentManifest, PACKAGE_IDX_FAKE_TEXT_CMF); RegisterCMFAssets(m_speechContentManifest, PACKAGE_IDX_FAKE_SPEECH_CMF); if (m_usingResourceGraph) { m_hackedLookedUpBundles = new HashSet <ulong>(); m_hackedBundleLookup = new Dictionary <ulong, ulong>(); DoBundleLookupHack(); } }
public ProductHandler_Tank(ClientHandler client, Stream stream) { _client = client; var clientArgs = client.CreateArgs.HandlerArgs as ClientCreateArgs_Tank ?? new ClientCreateArgs_Tank(); using (BinaryReader reader = new BinaryReader(stream)) { string str = Encoding.ASCII.GetString(reader.ReadBytes((int)stream.Length)); string[] array = str.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); if (FieldOrderCheck != array[0]) { throw new InvalidDataException($"ProductHandler_Tank: Root file field list mismatch ({array[0]})"); } RootFiles = new RootFile[array.Length - 1]; for (int i = 1; i < array.Length; i++) { RootFiles[i - 1] = new RootFile(array[i].Split('|')); } } if (!clientArgs.LoadManifest) { return; } int totalAssetCount = 0; foreach (RootFile rootFile in RootFiles.Reverse()) // cmf first, then apm { string extension = Path.GetExtension(rootFile.FileName); if (extension != ".cmf" && extension != ".apm") { continue; } string manifestName = Path.GetFileNameWithoutExtension(rootFile.FileName); if (manifestName == null) { throw new InvalidDataException(); } if (!manifestName.Contains(RegionDev)) { continue; // is a CN (china?) CMF. todo: support this } var locale = GetManifestLocale(manifestName); // ReSharper disable once ConvertIfStatementToSwitchStatement if (extension == ".cmf") { bool speech = manifestName.Contains(SpeechManifestName); if (speech) { if (locale != client.CreateArgs.SpeechLanguage) { continue; } } else { if (locale != client.CreateArgs.TextLanguage) { continue; } } ContentManifestFile cmf; using (Stream cmfStream = client.OpenCKey(rootFile.MD5)) { try { cmf = new ContentManifestFile(client, cmfStream, $"{manifestName}.cmf"); } catch (CryptographicException) { Logger.Error("CASC", "Fatal - CMF decryption failed. Please update TACTLib."); if (Debugger.IsAttached) { Debugger.Break(); } throw; } } if (speech) { SpeechContentManifest = cmf; } else { MainContentManifest = cmf; } totalAssetCount += cmf.Header.DataCount; } else if (extension == ".apm") { if (locale != client.CreateArgs.TextLanguage) { continue; } using (Stream apmStream = client.OpenCKey(rootFile.MD5)) { PackageManifest = new ApplicationPackageManifest(client, this, apmStream, manifestName); } } } Assets = new ConcurrentDictionary <ulong, Asset>(Environment.ProcessorCount + 2, totalAssetCount); for (int i = 0; i < PackageManifest.Header.PackageCount; i++) { var records = PackageManifest.Records[i]; for (int j = 0; j < records.Length; j++) { var record = records[j]; //Console.Out.WriteLine($"{record.GUID:X8} {record.Unknown1} {record.Unknown2} {Manifests[0].ContentManifest.Exists(record.GUID)} {Manifests[1].ContentManifest.Exists(record.GUID)}"); if (Assets.ContainsKey(record.GUID)) { continue; } Assets[record.GUID] = new Asset(i, j); } } for (int i = 0; i < 2; i++) { ContentManifestFile contentManifestFile; int cmfId = -(i + 1); if (cmfId == -1) { contentManifestFile = MainContentManifest; } else if (cmfId == -2) { contentManifestFile = SpeechContentManifest; } else { throw new Exception("wat"); } // main = -1 // speech = -2 Parallel.For(0, contentManifestFile.HashList.Length, new ParallelOptions { MaxDegreeOfParallelism = 4 }, j => { var cmfAsset = contentManifestFile.HashList[j]; if (Assets.ContainsKey(cmfAsset.GUID)) { return; } Assets[cmfAsset.GUID] = new Asset(cmfId, j); }); } }
/// <summary> /// Parse the root file into <see cref="RootFile"/> /// </summary> /// <param name="content"></param> /// <returns></returns> public static RootFile ParseRoot(MemoryStream contentStream) { var rootfile = new RootFile { Lookup = new MultiDictionary <ulong, RootEntry>(), FileDataIds = new MultiDictionary <uint, RootEntry>() }; var namedCount = 0; var unnamedCount = 0; var newRoot = false; using (var stream = new MemoryStream(BLTE.Parse(contentStream.ToArray()))) using (var reader = new BinaryReader(stream)) { var header = reader.ReadUInt32(); if (header == HeaderFmt) { var totalFiles = reader.ReadUInt32(); var namedFiles = reader.ReadUInt32(); newRoot = true; } else { reader.BaseStream.Position = 0; } while (reader.BaseStream.Position < reader.BaseStream.Length) { var count = reader.ReadUInt32(); var contentFlags = (ContentFlags)reader.ReadUInt32(); var localeFlags = (LocaleFlags)reader.ReadUInt32(); var rootEntries = new RootEntry[count]; var fileDataIds = new int[count]; var idx = 0; for (var i = 0; i < count; ++i) { rootEntries[i].LocaleFlags = localeFlags; rootEntries[i].ContentFlags = contentFlags; fileDataIds[i] = idx + reader.ReadInt32(); rootEntries[i].FileDataId = (uint)fileDataIds[i]; idx = fileDataIds[i] + 1; } if (!newRoot) { for (var i = 0; i < count; ++i) { rootEntries[i].MD5 = reader.Read <MD5Hash>(); rootEntries[i].Lookup = reader.ReadUInt64(); rootfile.Lookup.Add(rootEntries[i].Lookup, rootEntries[i]); rootfile.FileDataIds.Add(rootEntries[i].FileDataId, rootEntries[i]); } } else { for (var i = 0; i < count; ++i) { rootEntries[i].MD5 = reader.Read <MD5Hash>(); } for (var i = 0; i < count; ++i) { if (contentFlags.HasFlag(ContentFlags.NoNameHash)) { rootEntries[i].Lookup = 0; unnamedCount++; } else { rootEntries[i].Lookup = reader.ReadUInt64(); namedCount++; rootfile.Lookup.Add(rootEntries[i].Lookup, rootEntries[i]); } rootfile.FileDataIds.Add(rootEntries[i].FileDataId, rootEntries[i]); } } } } return(rootfile); }