private int UnpackTPF(TPF tpf, string relOutputDir, UnpackReport report) { if (tpf.Platform != TPF.TPFPlatform.PC) { return(0); } foreach (TPF.Texture texture in tpf) { try { string dir = $@"{Game.Settings.UnpackDirectory.TrimEnd('\\')}\{relOutputDir}"; string path = $@"{dir}\{texture.Name}.dds"; Directory.CreateDirectory(dir); File.WriteAllBytes(path, texture.Bytes); report.Files.Add(new UnpackReportFile(texture)); } catch (Exception ex) { throw new Exception($"Error in texture \"{texture.Name}\"", ex); } } return(tpf.Textures.Count); }
private int UnpackBinder(IBinder binder, string relOutputDir, UnpackReport report, CancellationToken cancelToken) { int textureCount = 0; foreach (BinderFile file in binder.Files) { if (cancelToken.IsCancellationRequested) { return(textureCount); } if (TPUtil.HasValidExtension(file.Name)) { try { byte[] bytes = file.Bytes; if (DCX.Is(bytes)) { bytes = DCX.Decompress(bytes); } if (TPF.IsRead(bytes, out TPF tpf)) { textureCount += UnpackTPF(tpf, relOutputDir, report); } else if (BND4.IsRead(bytes, out BND4 bnd)) { textureCount += UnpackBinder(bnd, relOutputDir, report, cancelToken); } else { throw new NotSupportedException("Unknown file type."); } } catch (Exception ex) { throw new Exception($"Error in binder file \"{file.Name}\"", ex); } } } return(textureCount); }
private int UnpackVirtualFile(VirtualFile vf, CancellationToken cancelToken) { byte[] bytes; long baseMemory; lock (this) { while (BaseMemoryCommitted > TPUtil.MAX_BASE_MEMORY) { Thread.Sleep(10); } if (cancelToken.IsCancellationRequested) { return(0); } bytes = vf.Load(); baseMemory = bytes.Length; Interlocked.Add(ref BaseMemoryCommitted, baseMemory); } try { string relOutputDir = TPUtil.GetRelativeOutputDir(vf.Path); if (DCX.Is(bytes)) { bytes = DCX.Decompress(bytes); } int textureCount; var report = new UnpackReport(); if (TPF.IsRead(bytes, out TPF tpf)) { textureCount = UnpackTPF(tpf, relOutputDir, report); } else if (BND4.IsRead(bytes, out BND4 bnd)) { textureCount = UnpackBinder(bnd, relOutputDir, report, cancelToken); } else if (BXF4.IsBDT(bytes)) { string ext = Path.GetExtension(vf.Path).Replace("bdt", "bhd"); string bhdPath = Path.ChangeExtension(vf.Path, ext); VirtualFile vfHeader = VirtualFS.Files[bhdPath]; byte[] bhdBytes = vfHeader.Load(); var bxf = BXF4.Read(bhdBytes, bytes); textureCount = UnpackBinder(bxf, relOutputDir, report, cancelToken); } else { throw new NotSupportedException("Unknown file type."); } if (report.Files.Count > 0) { File.WriteAllText($@"{Game.Settings.UnpackDirectory.TrimEnd('\\')}\{relOutputDir}\_report.txt", report.Write()); } return(textureCount); } finally { Interlocked.Add(ref BaseMemoryCommitted, -baseMemory); } }