public override Stream OpenEntry(ArcFile arc, Entry entry) { var pentry = entry as PackDatEntry; if (null == pentry || 0 == (pentry.Flags & 0x10000)) return arc.File.CreateStream (entry.Offset, entry.Size); byte[] input = new byte[pentry.Size]; if (pentry.Size != arc.File.View.Read (entry.Offset, input, 0, pentry.Size)) return arc.File.CreateStream (entry.Offset, entry.Size); unsafe { fixed (byte* buf_raw = input) { uint* encoded = (uint*)buf_raw; uint key = pentry.Size >> 2; key = (key << (((int)key & 7) + 8)) ^ key; for (uint i = entry.Size / 4; i != 0; --i ) { *encoded ^= key; int cl = (int)(*encoded++ % 24); key = (key << cl) | (key >> (32 - cl)); } } } return new MemoryStream (input); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var abm = arc as AbmArchive; var frame = entry as AbmEntry; if (null == abm || null == frame) return arc.File.CreateStream (entry.Offset, entry.Size); var frame_info = abm.FrameInfo; if (frame.Index != 0) { frame_info = frame_info.Clone(); frame_info.FrameOffset = (uint)frame.Offset; } using (var input = arc.File.CreateStream (0, (uint)arc.File.MaxOffset)) using (var reader = new AbmReader (input, frame_info)) { // emulate TGA image var header = new byte[0x12]; header[2] = 2; LittleEndian.Pack ((ushort)frame_info.Width, header, 0xC); LittleEndian.Pack ((ushort)frame_info.Height, header, 0xE); header[0x10] = (byte)reader.BPP; header[0x11] = 0x20; var pixels = reader.Unpack(); return new PrefixStream (header, new MemoryStream (pixels)); } }
public void OpenArchive() { string assetPath = AssetDatabase.GetAssetPath(_archiveFile); BinaryReader reader = null; try { reader = new BinaryReader(new FileStream(assetPath, FileMode.Open, FileAccess.Read, FileShare.Read)); _header = new ArcHeader(reader); _files = new List<ArcFile>((int)_header.fileCount); for (int fileI = 0; fileI != (int)_header.fileCount; fileI++) { ArcFile file = new ArcFile(reader); file.ArchiveName = Path.GetFileName(assetPath); file.FileNumber = fileI; _files.Add(file); } } catch (Exception e) { Debug.LogError("Path " + assetPath); Debug.LogException(e); if (reader != null) { reader.Close(); } } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var input = arc.File.CreateStream (entry.Offset, entry.Size); if (!entry.Name.EndsWith (".scb", StringComparison.InvariantCultureIgnoreCase)) return input; return new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var pent = entry as PnaEntry; if (null == pent) return base.OpenEntry (arc, entry); ImageData image; using (var input = arc.File.CreateStream (entry.Offset, entry.Size)) image = ImageFormat.Read (input); var bitmap = image.Bitmap; if (bitmap.Format.BitsPerPixel != 32) { bitmap = new FormatConvertedBitmap (bitmap, PixelFormats.Bgra32, null, 0); } int stride = bitmap.PixelWidth * 4; var pixels = new byte[stride * bitmap.PixelHeight]; bitmap.CopyPixels (pixels, stride, 0); // restore colors premultiplied by alpha for (int i = 0; i < pixels.Length; i += 4) { int alpha = pixels[i+3]; if (alpha != 0 && alpha != 0xFF) { pixels[i] = (byte)(pixels[i] * 0xFF / alpha); pixels[i+1] = (byte)(pixels[i+1] * 0xFF / alpha); pixels[i+2] = (byte)(pixels[i+2] * 0xFF / alpha); } } return TgaStream.Create (pent.Info, pixels); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var pent = entry as PackedEntry; Stream input = arc.File.CreateStream (entry.Offset, entry.Size); if (null != pent && pent.IsPacked) { Stream unpacked; using (input) { var data = new byte[pent.UnpackedSize]; UnpackEntry (input, data); unpacked = new MemoryStream (data); } input = unpacked; } if (input.Length > 4 && input.Length < 0x10000) { using (var reader = new ArcView.Reader (input)) { int unpacked_size = reader.ReadUInt16(); int packed_size = reader.ReadUInt16(); if (packed_size == input.Length-4) { using (input) { var data = new byte[unpacked_size]; UnpackLz77 (input, data); return new MemoryStream (data); } } input.Position = 0; } } return input; }
public override Stream OpenEntry(ArcFile arc, Entry entry) { // emulate TGA image var offset = entry.Offset; var info = new Hg2MetaData { HeaderSize = 0x4C, Width = arc.File.View.ReadUInt32 (offset), Height = arc.File.View.ReadUInt32 (offset+4), BPP = arc.File.View.ReadInt32 (offset+8), DataPacked = arc.File.View.ReadInt32 (offset+0x14), DataUnpacked= arc.File.View.ReadInt32 (offset+0x18), CtlPacked = arc.File.View.ReadInt32 (offset+0x1C), CtlUnpacked = arc.File.View.ReadInt32 (offset+0x20), CanvasWidth = arc.File.View.ReadUInt32 (offset+0x2C), CanvasHeight= arc.File.View.ReadUInt32 (offset+0x30), OffsetX = arc.File.View.ReadInt32 (offset+0x34), OffsetY = arc.File.View.ReadInt32 (offset+0x38), }; using (var input = arc.File.CreateStream (entry.Offset, entry.Size)) using (var reader = new Hg2Reader (input, info)) { return TgaStream.Create (info, reader.Unpack(), true); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { if (entry.Size < 0x2C || !arc.File.View.AsciiEqual (entry.Offset, "ONCE")) return base.OpenEntry (arc, entry); var input = arc.File.CreateStream (entry.Offset+0x2C, entry.Size-0x2C); return new EncryptedStream (input); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { if (!entry.Name.EndsWith (".msc", StringComparison.InvariantCultureIgnoreCase)) return base.OpenEntry (arc, entry); var data = arc.File.View.ReadBytes (entry.Offset, entry.Size); for (int i = 0; i < data.Length; ++i) data[i] ^= 0x88; return new MemoryStream (data); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var warc = arc as WagArchive; if (null == warc) return arc.File.CreateStream (entry.Offset, entry.Size); var data = arc.File.View.ReadBytes (entry.Offset, entry.Size); Decrypt ((uint)entry.Offset, warc.Key, data); return new MemoryStream (data); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { if ("CODE" != entry.Name) return arc.File.CreateStream (entry.Offset, entry.Size); var code = new byte[entry.Size]; arc.File.View.Read (entry.Offset, code, 0, entry.Size); DecryptCodeSection (code); return new MemoryStream (code); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { if (entry.Size > 8 && arc.File.View.AsciiEqual (entry.Offset+4, "HDJ\0")) return OpenImage (arc, entry); else if (entry.Size > 12 && 'W' == arc.File.View.ReadByte (entry.Offset+4) && arc.File.View.AsciiEqual (entry.Offset+8, "RIFF")) return OpenAudio (arc, entry); else return base.OpenEntry (arc, entry); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var pent = entry as PackedEntry; if (null == pent || !pent.IsPacked) return base.OpenEntry (arc, entry); using (var input = arc.File.CreateStream (entry.Offset, entry.Size)) using (var bmr = new BmrDecoder (input)) { bmr.Unpack(); return new MemoryStream (bmr.Data); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { if (!(entry.Size > 8 && arc.File.View.AsciiEqual (entry.Offset, "acp\0"))) return base.OpenEntry (arc, entry); int unpacked_size = Binary.BigEndian (arc.File.View.ReadInt32 (entry.Offset+4)); using (var input = arc.File.CreateStream (entry.Offset+8, entry.Size-8)) using (var decoder = new LzwDecoder (input, unpacked_size)) { decoder.Unpack(); return new MemoryStream (decoder.Output); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var input = arc.File.CreateStream (entry.Offset, entry.Size); var pentry = entry as PackedEntry; if (null == pentry || !pentry.IsPacked) return input; using (input) { byte[] data = new byte[pentry.UnpackedSize]; LzssUnpack (input, data); return new MemoryStream (data); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var input = base.OpenEntry (arc, entry); var pent = entry as PackedEntry; if (null == pent || !pent.IsPacked) return input; var data = new byte[pent.UnpackedSize]; using (var reader = new ShsCompression (input)) { reader.Unpack (data); return new MemoryStream (data); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { if (entry.Size <= 0x10 || !arc.File.View.AsciiEqual (entry.Offset, "AFF\0")) return base.OpenEntry (arc, entry); uint data_size = entry.Size - 0x10u; uint encrypted_length = Math.Min (0x40u, data_size); var prefix = arc.File.View.ReadBytes (entry.Offset+0x10, encrypted_length); for (int i = 0; i < prefix.Length; ++i) prefix[i] ^= AffKey[i & 0xF]; if (data_size <= 0x40) return new MemoryStream (prefix); var rest = arc.File.CreateStream (entry.Offset+0x10+encrypted_length, data_size-encrypted_length); return new PrefixStream (prefix, rest); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { if (entry.Size <= 8 || !entry.Name.EndsWith (".snc", StringComparison.InvariantCultureIgnoreCase) || !arc.File.View.AsciiEqual (entry.Offset, "CMP_")) return arc.File.CreateStream (entry.Offset, entry.Size); int unpacked_size = arc.File.View.ReadInt32 (entry.Offset+4); using (var input = arc.File.CreateStream (entry.Offset+8, entry.Size-8)) using (var lzss = new LzssReader (input, (int)(entry.Size - 8), unpacked_size)) { lzss.FrameFill = 0x20; lzss.Unpack(); return new MemoryStream (lzss.Data); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var ement = entry as EmEntry; var emarc = arc as EmeArchive; if (null == ement || null == emarc) return base.OpenEntry (arc, entry); if (3 == ement.SubType) return OpenScript (emarc, ement); else if (4 == ement.SubType) return OpenImage (emarc, ement); else if (5 == ement.SubType && entry.Size > 4) return OpenT5 (emarc, ement); else return base.OpenEntry (arc, entry); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var pent = entry as PackedEntry; if (null == pent || !pent.IsPacked) return base.OpenEntry (arc, entry); var output = new byte[pent.UnpackedSize]; using (var input = arc.File.CreateStream (entry.Offset, entry.Size)) { if (Unpack (input, output)) return new MemoryStream (output); else return base.OpenEntry (arc, entry); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var input = arc.File.CreateStream (entry.Offset, entry.Size); var pentry = entry as PackedEntry; if (null == pentry || !pentry.IsPacked) return input; try { return new ZLibStream (input, CompressionMode.Decompress); } catch { input.Dispose(); throw; } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var cent = entry as CgfEntry; if (null == cent) return base.OpenEntry (arc, entry); var offset = entry.Offset; var header = new byte[12]; if (2 == cent.Flags) { arc.File.View.Read (offset, header, 0, 8); offset += 0x10; } uint packed_size = arc.File.View.ReadUInt32 (offset); arc.File.View.Read (offset+4, header, 8, 4); var input = arc.File.CreateStream (offset+8, packed_size); return new PrefixStream (header, input); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var input = arc.File.CreateStream (entry.Offset, entry.Size); if (entry.Size <= 8) return input; var sign = FormatCatalog.ReadSignature (input); if (0x32434c5a != sign) // 'ZLC2' { input.Position = 0; return input; } using (input) using (var reader = new Zlc2Reader (input, (int)entry.Size)) { reader.Unpack(); return new MemoryStream (reader.Data); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var input = arc.File.CreateStream (entry.Offset, entry.Size); var packed_entry = entry as SPackEntry; if (null == packed_entry || !packed_entry.IsPacked) return input; if (1 == packed_entry.Method) return new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read); if (2 == packed_entry.Method) { using (var reader = new PackedReader (packed_entry, input)) { reader.Unpack(); return new MemoryStream (reader.Data); } } return input; }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var bdf = arc as BdfArchive; var frame = entry as BdfFrame; if (null == bdf || null == frame) return arc.File.CreateStream (entry.Offset, entry.Size); var pixels = bdf.ReadFrame (frame); var header = new byte[0x12]; header[2] = 2; if (frame.Incremental) frame = bdf.Dir.First() as BdfFrame; LittleEndian.Pack ((ushort)frame.Width, header, 0xc); LittleEndian.Pack ((ushort)frame.Height, header, 0xe); header[0x10] = 24; header[0x11] = 0x20; return new PrefixStream (header, new MemoryStream (pixels)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var iarc = arc as IarArchive; if (null == iarc) return base.OpenEntry (arc, entry); try { int flags = arc.File.View.ReadUInt16 (entry.Offset); var image = new IarImage (iarc, entry); if (0 != (flags & 0x1000)) image = CombineLayers (image, iarc); else if (0 != (flags & 0x800)) image = CombineImage (image, iarc); if (null == image) return base.OpenEntry (arc, entry); // internal 'IAR SAS5' format var header = new byte[0x28+image.Info.PaletteSize]; using (var mem = new MemoryStream (header)) using (var writer = new BinaryWriter (mem)) { writer.Write (0x00524149); // 'IAR' writer.Write (0x35534153); // 'SAS5' writer.Write (image.Info.Width); writer.Write (image.Info.Height); writer.Write (image.Info.OffsetX); writer.Write (image.Info.OffsetY); writer.Write (image.Info.BPP); writer.Write (image.Info.Stride); writer.Write (image.Info.PaletteSize); writer.Write (image.Data.Length); if (null != image.Palette) writer.Write (image.Palette, 0, image.Palette.Length); return new PrefixStream (header, new MemoryStream (image.Data)); } } catch (Exception X) { Trace.WriteLine (X.Message, entry.Name); return base.OpenEntry (arc, entry); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { if (0 == entry.Size) return Stream.Null; var g00arc = (G00Archive)arc; var g00ent = (G00Entry)entry; using (var input = new MemoryStream (g00arc.Bitmap)) using (var reader = new BinaryReader (input)) { input.Position = g00ent.Offset; int tile_type = reader.ReadUInt16(); int count = reader.ReadUInt16(); if (tile_type != 1) throw new InvalidFormatException(); input.Seek (0x70, SeekOrigin.Current); int dst_stride = (int)g00arc.ImageInfo.Width * 4; var pixels = new byte[(int)g00arc.ImageInfo.Height * dst_stride]; for (int i = 0; i < count; ++i) { int tile_x = reader.ReadUInt16(); int tile_y = reader.ReadUInt16(); reader.ReadInt16(); int tile_width = reader.ReadUInt16(); int tile_height = reader.ReadUInt16(); input.Seek (0x52, SeekOrigin.Current); tile_x += g00ent.X; tile_y += g00ent.Y; if (tile_x + tile_width > g00arc.ImageInfo.Width || tile_y + tile_height > g00arc.ImageInfo.Height) throw new InvalidFormatException(); int dst = tile_y * dst_stride + tile_x * 4; int tile_stride = tile_width * 4; for (int row = 0; row < tile_height; ++row) { reader.Read (pixels, dst, tile_stride); dst += dst_stride; } } return TgaStream.Create (g00arc.ImageInfo, pixels); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { // emulate TGA image var offset = entry.Offset; var info = new S25MetaData { Width = arc.File.View.ReadUInt32 (offset), Height = arc.File.View.ReadUInt32 (offset+4), OffsetX = arc.File.View.ReadInt32 (offset+8), OffsetY = arc.File.View.ReadInt32 (offset+12), BPP = 32, FirstOffset = (uint)(offset + 0x14), Incremental = 0 != (arc.File.View.ReadUInt32 (offset+0x10) & 0x80000000u), }; using (var input = arc.File.CreateStream (0, (uint)arc.File.MaxOffset)) using (var reader = new S25Format.Reader (input, info)) { return TgaStream.Create (info, reader.Unpack()); } }
public override void Init(ArcFile arc) { var list_bin = arc.Dir.FirstOrDefault (e => e.Name == "plugin/list.bin") as Xp3Entry; if (null == list_bin || list_bin.UnpackedSize <= 0x30) return; var bin = new byte[list_bin.UnpackedSize]; using (var input = arc.OpenEntry (list_bin)) input.Read (bin, 0, bin.Length); for (int i = 0; i < 3; ++i) { bin = DecodeListBin (bin); if (null == bin) return; } if (null == EncryptionThresholdMap) EncryptionThresholdMap = new Dictionary<uint, uint>(); else EncryptionThresholdMap.Clear(); ParseListBin (bin); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { // emulate TGA image var offset = entry.Offset+8; var info = new HgMetaData { HeaderSize = arc.File.View.ReadUInt32 (offset), Width = arc.File.View.ReadUInt32 (offset+8), Height = arc.File.View.ReadUInt32 (offset+0xC), BPP = arc.File.View.ReadInt32 (offset+0x10), OffsetX = arc.File.View.ReadInt32 (offset+0x14), OffsetY = arc.File.View.ReadInt32 (offset+0x18), CanvasWidth = arc.File.View.ReadUInt32 (offset+0x1C), CanvasHeight = arc.File.View.ReadUInt32 (offset+0x20), }; using (var input = arc.File.CreateStream (entry.Offset, entry.Size)) using (var reader = new Hg3Reader (input, info)) { var pixels = reader.Unpack(); return TgaStream.Create (info, pixels, reader.Flipped); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var parc = (PmxArchive)arc; return(new StreamRegion(parc.BaseStream, entry.Offset, entry.Size, true)); }
public override ImageData Read(IBinaryStream file, ImageMetaData info) { var meta = (DrefMetaData)info; ArcFile dpak = null; try { int layers_count = meta.Layers.Count(); WriteableBitmap canvas = null; foreach (var path in meta.Layers) { if (null == dpak || dpak.File.Name != path.Item1) { if (dpak != null) { dpak.Dispose(); dpak = null; } var view = VFS.OpenView(path.Item1); try { dpak = Psb.Value.TryOpen(view); if (null == dpak) { throw new InvalidFormatException(); } } catch { view.Dispose(); throw; } } var entry = dpak.Dir.FirstOrDefault(e => e.Name == path.Item2); if (null == entry) { throw new InvalidFormatException(); } using (var decoder = dpak.OpenImage(entry)) { if (1 == layers_count) { return(decoder.Image); } if (null == canvas) { canvas = new WriteableBitmap(decoder.Image.Bitmap); meta.Width = decoder.Info.Width; meta.Height = decoder.Info.Height; meta.OffsetX = decoder.Info.OffsetX; meta.OffsetY = decoder.Info.OffsetY; } else { BlendLayer(canvas, decoder.Image); } } } if (null == canvas) { throw new InvalidFormatException(); } canvas.Freeze(); return(new ImageData(canvas, meta)); } finally { if (dpak != null) { dpak.Dispose(); } } }
Stream OpenTpw(ArcFile arc, PackedEntry entry) { var output = new byte[entry.UnpackedSize]; using (var input = arc.File.CreateStream(entry.Offset, entry.Size)) { input.Position = 8; var offsets = new int[4]; offsets[0] = input.ReadUInt16(); offsets[1] = offsets[0] * 2; offsets[2] = offsets[0] * 3; offsets[3] = offsets[0] * 4; int dst = 0; while (dst < output.Length) { byte ctl = input.ReadUInt8(); if (0 == ctl) { break; } int count; if (ctl < 0x40) { input.Read(output, dst, ctl); dst += ctl; } else if (ctl <= 0x6F) { if (0x6F == ctl) { count = input.ReadUInt16(); } else { count = (ctl + 0xC3) & 0xFF; } byte v = input.ReadUInt8(); while (count-- > 0) { output[dst++] = v; } } else if (ctl <= 0x9F) { if (ctl == 0x9F) { count = input.ReadUInt16(); } else { count = (ctl + 0x92) & 0xFF; } byte v1 = input.ReadUInt8(); byte v2 = input.ReadUInt8(); while (count-- > 0) { output[dst++] = v1; output[dst++] = v2; } } else if (ctl <= 0xBF) { if (ctl == 0xBF) { count = input.ReadUInt16(); } else { count = ((ctl + 0x62) & 0xFF); } input.Read(output, dst, 3); if (count > 0) { count *= 3; Binary.CopyOverlapped(output, dst, dst + 3, count - 3); dst += count; } } else { count = (ctl & 0x3F) + 3; int offset = input.ReadUInt8(); offset = (offset & 0x3F) - offsets[offset >> 6]; Binary.CopyOverlapped(output, dst + offset, dst, count); dst += count; } } return(new BinMemoryStream(output, entry.Name)); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { return(((ZipEntry)entry).NativeEntry.Open()); }
void CopyAmiEntry(ArcFile base_archive, Entry entry, Stream output) { using (var input = base_archive.File.CreateStream(entry.Offset, entry.Size)) input.CopyTo(output); }
public async Task ArcFileCommuTest(string arcName, string outputXlsx) { using ArcFile arcFile = new ArcFile(arcName); await arcFile.ExtractCommusToXlsx(outputXlsx, true, progress); }
public async Task SaveArcAs(string filename) { using (ArcFile arcFile = new ArcFile(filename)) { await arcFile.SaveAs("temp.arc", progress); } bool eq = Compare.CompareFiles(filename, "temp.arc") && Compare.CompareFiles(ArcFile.GetBinName(filename), "temp.bin"); File.Delete("temp.arc"); File.Delete("temp.bin"); Assert.IsTrue(eq); }
/// <summary> /// Perform necessary initialization specific to an archive being opened. /// </summary> public virtual void Init(ArcFile arc) { }
public override IImageDecoder OpenImage(ArcFile arc, Entry entry) { var input = arc.File.CreateStream(entry.Offset, entry.Size); return(new MngFrameDecoder(input)); }
public override ArcFile TryOpen(ArcView file) { long base_offset = 0; if (0x5a4d == file.View.ReadUInt16(0)) // 'MZ' { base_offset = SkipExeHeader(file); } if (!file.View.AsciiEqual(base_offset, SignatureBytes)) { return(null); } long dir_offset = base_offset + file.View.ReadInt64(base_offset + 0x0b); if (dir_offset < 0x13 || dir_offset >= file.MaxOffset) { return(null); } if (0x80 == file.View.ReadUInt32(dir_offset)) { dir_offset = base_offset + file.View.ReadInt64(dir_offset + 9); if (dir_offset < 0x13 || dir_offset >= file.MaxOffset) { return(null); } } int header_type = file.View.ReadByte(dir_offset); if (0 != header_type && 1 != header_type) { return(null); } Stream header_stream; if (0 == header_type) // read unpacked header { long header_size = file.View.ReadInt64(dir_offset + 1); if (header_size > uint.MaxValue) { return(null); } header_stream = file.CreateStream(dir_offset + 9, (uint)header_size); } else // read packed header { long packed_size = file.View.ReadInt64(dir_offset + 1); if (packed_size > uint.MaxValue) { return(null); } long header_size = file.View.ReadInt64(dir_offset + 9); using (var input = file.CreateStream(dir_offset + 17, (uint)packed_size)) header_stream = ZLibCompressor.DeCompress(input); } var crypt_algorithm = new Lazy <ICrypt> (() => QueryCryptAlgorithm(file), false); var dir = new List <Entry>(); dir_offset = 0; using (var header = new BinaryReader(header_stream, Encoding.Unicode)) using (var filename_map = new FilenameMap()) { while (-1 != header.PeekChar()) { uint entry_signature = header.ReadUInt32(); long entry_size = header.ReadInt64(); if (entry_size < 0) { return(null); } dir_offset += 12 + entry_size; if (0x656C6946 == entry_signature) // "File" { var entry = new Xp3Entry(); while (entry_size > 0) { uint section = header.ReadUInt32(); long section_size = header.ReadInt64(); entry_size -= 12; if (section_size > entry_size) { break; } entry_size -= section_size; long next_section_pos = header.BaseStream.Position + section_size; switch (section) { case 0x6f666e69: // "info" if (entry.Size != 0 || !string.IsNullOrEmpty(entry.Name)) { goto NextEntry; // ambiguous entry, ignore } entry.IsEncrypted = 0 != header.ReadUInt32(); long file_size = header.ReadInt64(); long packed_size = header.ReadInt64(); if (file_size >= uint.MaxValue || packed_size > uint.MaxValue || packed_size > file.MaxOffset) { goto NextEntry; } entry.IsPacked = file_size != packed_size; entry.Size = (uint)packed_size; entry.UnpackedSize = (uint)file_size; if (entry.IsEncrypted || ForceEncryptionQuery) { entry.Cipher = crypt_algorithm.Value; } else { entry.Cipher = NoCryptAlgorithm; } var name = entry.Cipher.ReadName(header); if (null == name) { goto NextEntry; } if (entry.Cipher.ObfuscatedIndex && ObfuscatedPathRe.IsMatch(name)) { goto NextEntry; } if (filename_map.Count > 0) { name = filename_map.Get(entry.Hash, name); } if (name.Length > 0x100) { goto NextEntry; } entry.Name = name; entry.Type = FormatCatalog.Instance.GetTypeFromName(name); entry.IsEncrypted = !(entry.Cipher is NoCrypt) && !(entry.Cipher.StartupTjsNotEncrypted && "startup.tjs" == name); break; case 0x6d676573: // "segm" int segment_count = (int)(section_size / 0x1c); if (segment_count > 0) { for (int i = 0; i < segment_count; ++i) { bool compressed = 0 != header.ReadInt32(); long segment_offset = base_offset + header.ReadInt64(); long segment_size = header.ReadInt64(); long segment_packed_size = header.ReadInt64(); if (segment_offset > file.MaxOffset || segment_packed_size > file.MaxOffset) { goto NextEntry; } var segment = new Xp3Segment { IsCompressed = compressed, Offset = segment_offset, Size = (uint)segment_size, PackedSize = (uint)segment_packed_size }; entry.Segments.Add(segment); } entry.Offset = entry.Segments.First().Offset; } break; case 0x726c6461: // "adlr" if (4 == section_size) { entry.Hash = header.ReadUInt32(); } break; default: // unknown section break; } header.BaseStream.Position = next_section_pos; } if (!string.IsNullOrEmpty(entry.Name) && entry.Segments.Any()) { if (entry.Cipher.ObfuscatedIndex) { DeobfuscateEntry(entry); } dir.Add(entry); } } else if (entry_size > 7) { // 0x6E666E68 == entry_signature // "hnfn" // 0x6C696D73 == entry_signature // "smil" // 0x46696C65 == entry_signature // "eliF" // 0x757A7559 == entry_signature // "Yuzu" uint hash = header.ReadUInt32(); int name_size = header.ReadInt16(); if (name_size > 0) { entry_size -= 6; if (name_size * 2 <= entry_size) { var filename = new string (header.ReadChars(name_size)); filename_map.Add(hash, filename); } } } NextEntry: header.BaseStream.Position = dir_offset; } } if (0 == dir.Count) { return(null); } var arc = new ArcFile(file, this, dir); try { if (crypt_algorithm.IsValueCreated) { crypt_algorithm.Value.Init(arc); } return(arc); } catch { arc.Dispose(); throw; } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { return(((CabEntry)entry).Info.OpenRead()); }
public async Task ArcParameterIndividualTest(string arcName, string outputXlsx) { using ArcFile arcFile = new ArcFile(arcName); await arcFile.ExtractParameterToXlsx(outputXlsx, true, progress); }
public override void Create(Stream output, IEnumerable <Entry> list, ResourceOptions options, EntryCallback callback) { ArcFile base_archive = null; var ami_options = GetOptions <AmiOptions> (options); if (null != ami_options && ami_options.UseBaseArchive && !string.IsNullOrEmpty(ami_options.BaseArchive)) { var base_file = new ArcView(ami_options.BaseArchive); try { if (base_file.View.ReadUInt32(0) == Signature) { base_archive = TryOpen(base_file); } if (null == base_archive) { throw new InvalidFormatException(string.Format("{0}: base archive could not be read", Path.GetFileName(ami_options.BaseArchive))); } base_file = null; } finally { if (null != base_file) { base_file.Dispose(); } } } try { var file_table = new SortedDictionary <uint, PackedEntry>(); if (null != base_archive) { foreach (AmiEntry entry in base_archive.Dir) { file_table[entry.Id] = entry; } } int update_count = UpdateFileTable(file_table, list); if (0 == update_count) { throw new InvalidFormatException(arcStrings.AMINoFiles); } uint file_count = (uint)file_table.Count; if (null != callback) { callback((int)file_count + 1, null, null); } int callback_count = 0; long start_offset = output.Position; uint data_offset = file_count * 16 + 16; output.Seek(data_offset, SeekOrigin.Current); foreach (var entry in file_table) { if (null != callback) { callback(callback_count++, entry.Value, arcStrings.MsgAddingFile); } long current_offset = output.Position; if (current_offset > uint.MaxValue) { throw new FileSizeException(); } if (entry.Value is AmiEntry) { CopyAmiEntry(base_archive, entry.Value, output); } else { entry.Value.Size = WriteAmiEntry(entry.Value, output); } entry.Value.Offset = (uint)current_offset; } if (null != callback) { callback(callback_count++, null, arcStrings.MsgWritingIndex); } output.Position = start_offset; using (var header = new BinaryWriter(output, Encoding.ASCII, true)) { header.Write(Signature); header.Write(file_count); header.Write(data_offset); header.Write((uint)0); foreach (var entry in file_table) { header.Write(entry.Key); header.Write((uint)entry.Value.Offset); header.Write((uint)entry.Value.UnpackedSize); header.Write((uint)entry.Value.Size); } } } finally { if (null != base_archive) { base_archive.Dispose(); } } }
//[DataRow("hdd.arc", "images/hdd_images")] public async Task ExtractAllImagesTest(string arcName, string outDir) { using ArcFile arcFile = new ArcFile(arcName); await arcFile.ExtractAllImages(outDir); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var input = arc.File.CreateStream(entry.Offset, entry.Size); return(new XoredStream(input, 0x90)); }
public async Task ExtractLyricsTest(string arcName, string outDir) { using ArcFile arcFile = new ArcFile(arcName); await arcFile.ExtractLyrics(outDir, true); }
Stream OpenSpdc(ArcFile arc, Entry entry) { int signature = arc.File.View.ReadInt32(entry.Offset); if (0x43445053 == signature || 0x38445053 == signature || entry.Size <= 0x14) { return(arc.File.CreateStream(entry.Offset, entry.Size)); } var header = arc.File.View.ReadBytes(entry.Offset, 0x14); byte header_key = (byte)(header[0x12] + header[0x10]); header[0] -= header_key; header[1] -= header_key; header[2] -= header_key; header[3] -= header_key; bool spdc_entry = Binary.AsciiEqual(header, "SPD") && (header[3] == 'C' || header[3] == '8'); if (!spdc_entry) { LittleEndian.Pack(signature, header, 0); var tcde = entry as TcdEntry; var tcda = arc as TcdArchive; if (tcda != null && tcde != null) { if (null == tcda.Key) { foreach (var key in TcdOpener.KnownKeys.Values) { int first = signature + key * (tcde.Index + 3); if (0x43445053 == first) // 'SPDC' { tcda.Key = key; spdc_entry = true; break; } } } else if (0x43445053 == (signature + tcda.Key.Value * (tcde.Index + 3))) { spdc_entry = true; } if (spdc_entry && 0 != tcda.Key.Value) { unsafe { fixed(byte *raw = header) { int *dw = (int *)raw; for (int i = 0; i < 5; ++i) { dw[i] += tcda.Key.Value * (tcde.Index + 3 + i); } } } } } } var rest = arc.File.CreateStream(entry.Offset + 0x14, entry.Size - 0x14); return(new PrefixStream(header, rest)); }
static void Main(string[] args) { Console.WriteLine("ONE Eternal Patch v1.0"); Console.WriteLine("developed by Sep7\n"); ////////// //INPUTS ////////// string inputLanguage = ""; do { Console.WriteLine("Enter 1 if you want to patch the Japanese Version."); Console.WriteLine("Enter 2 if you want to patch the English translated Version."); inputLanguage = Console.ReadLine(); if (inputLanguage.Length != 1 || (inputLanguage.Substring(0, 1) != "1" && inputLanguage.Substring(0, 1) != "2")) { Console.WriteLine("Syntax Error.\n"); } } while (inputLanguage.Length != 1 || (inputLanguage.Substring(0, 1) != "1" && inputLanguage.Substring(0, 1) != "2")); string inputBonusCG = ""; do { Console.WriteLine("\nEnter 1 if you want to add the bonus CGs."); Console.WriteLine("Enter 2 if you want to remove them."); inputBonusCG = Console.ReadLine(); if (inputBonusCG.Length != 1 || (inputBonusCG.Substring(0, 1) != "1" && inputBonusCG.Substring(0, 1) != "2")) { Console.WriteLine("Syntax Error."); } } while (inputBonusCG.Length != 1 || (inputBonusCG.Substring(0, 1) != "1" && inputBonusCG.Substring(0, 1) != "2")); ////////////////////////////// //EXTRACTING OF THE PATCH FILES ////////////////////////////// //First, we create a view of the file that'll allow us to work on it, the file is still encrypted. ArcView originalFile = null; ArcView patchFile = null; try { patchFile = new ArcView("./ONE_Patch_Files"); } catch (System.IO.FileNotFoundException e) { Console.WriteLine("\nError: the file \"ONE_Patch_Files\" was not found.\n" + "Make sure to place it in the same directory as the executable.\n\n" + "Error details: " + e + "\n\nPress any key to continue."); Console.ReadKey(true); System.Environment.Exit(1); } catch (System.UnauthorizedAccessException e) { Console.WriteLine("\nError: the file \"ONE_Patch_Files\" can't be accessed.\n" + "Make sure that the file and the current folder are not in read only access.\n\n" + "Error details: " + e + "\n\nPress any key to continue."); Console.ReadKey(true); System.Environment.Exit(1); } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(true); System.Environment.Exit(1); } LstOpener lst = new LstOpener(); List <Entry> resultFilesList = new List <Entry>(); ArcFile arcOriginalFiles = null; ArcFile arcPatchFiles = null; ArchiveFileSystem afsOriginalFiles = null; ArchiveFileSystem afsPatchFiles = null; String suffix = ""; try { //then, we want to get the encrypted file with the LstOpener //the arcfile is composed of the view on the original file, of an instance of LstOpener used to determinate the format //and of a list of all the files/entries with their names, type, offset and size arcPatchFiles = lst.TryOpen(patchFile); } catch (System.UnauthorizedAccessException e) { Console.WriteLine("\nError: the file \"ONE_Patch_Files.lst\" can't be accessed.\n" + "Make sure that the file and the current folder are not in read only access.\n\n" + "Error details: " + e + "\n\nPress any key to continue."); Console.ReadKey(true); System.Environment.Exit(1); } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(true); System.Environment.Exit(1); } try { //create a dictionary of data where the key is equal to the name of the entry and where the content is equal to the current entry afsPatchFiles = arcPatchFiles.CreateFileSystem(); } catch (System.NullReferenceException e) { Console.WriteLine("\nError: the file \"ONE_Patch_Files.lst\" was not found.\n" + "Make sure to place it in the same directory as the executable.\n\n" + "Error details: " + e + "\n\nPress any key to continue."); Console.ReadKey(true); System.Environment.Exit(1); } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(true); System.Environment.Exit(1); } List <Entry> patchFilesList = new List <Entry>(); //Remove the Bonus CGs in the Japanese version if (inputBonusCG.Substring(0, 1) == "2" && inputLanguage.Substring(0, 1) == "1") { suffix = "_JAP"; } //Remove the Bonus CGs in the English version else if (inputBonusCG.Substring(0, 1) == "2" && inputLanguage.Substring(0, 1) == "2") { suffix = "_ENG"; } //Add the Bonus CGs in the Japanese version else if (inputBonusCG.Substring(0, 1) == "1" && inputLanguage.Substring(0, 1) == "1") { suffix = "_JAPBCG"; } //Add the Bonus CGs in the English version else { suffix = "_ENGBCG"; } //Scripts patchFilesList.Add(afsPatchFiles.FindFile("AK26" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEAK" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMO" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMS" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMU" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMZ" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODENN" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("DS01" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("DS05" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("DS07" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("DS09" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("DS10_A" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("DS19" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("MS22" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("MS25" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("MS27" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("MY24" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("NV30" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("RM24" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("SBD25N1" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("SBRM14N1" + suffix + ".SNX")); patchFilesList.Add(afsPatchFiles.FindFile("SBRM17M1" + suffix + ".SNX")); //PNGs if (inputBonusCG.Substring(0, 1) == "1") { patchFilesList.Add(afsPatchFiles.FindFile("BG400.PNG")); } patchFilesList.Add(afsPatchFiles.FindFile("CGMODEAKBK" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEAKCHIP" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMOBK" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMOCHIP" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMSBK" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMSCHIP" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMUBK" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMUCHIP" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMZBK" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODEMZCHIP" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODENNBK" + suffix + ".PNG")); patchFilesList.Add(afsPatchFiles.FindFile("CGMODENNCHIP" + suffix + ".PNG")); if (inputBonusCG.Substring(0, 1) == "1") { patchFilesList.Add(afsPatchFiles.FindFile("FGAK17.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGAK18.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMI17.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMI18.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMI19.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMS18.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMS19.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMY16.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMY17.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMZ17.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGMZ18.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGRM16.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGRM17.PNG")); patchFilesList.Add(afsPatchFiles.FindFile("FGRM18.PNG")); } //This file only exists in the English translated version and is placed at the end of the archive for some reasons. //I'm pretty sure it's a mistake of the TL team but I prefer to update it, just in case. if (inputLanguage.Substring(0, 1) == "2") { patchFilesList.Add(afsPatchFiles.FindFile("CGMODEAKMU" + suffix + ".PNG")); } List <String> filesListToNotUpdate = new List <String> { "BG400.PNG", "FGAK17.PNG", "FGAK18.PNG", "FGMI17.PNG", "FGMI18.PNG", "FGMI19.PNG", "FGMS18.PNG", "FGMS19.PNG", "FGMY16.PNG", "FGMY17.PNG", "FGMZ17.PNG", "FGMZ18.PNG", "FGRM16.PNG", "FGRM17.PNG", "FGRM18.PNG" }; ////////////////////////////// //EXTRACTING OF THE ORIGINAL FILES ////////////////////////////// try { originalFile = new ArcView("./one"); } catch (System.IO.FileNotFoundException e) { Console.WriteLine("\nError: the file \"one\" was not found.\n" + "Make sure to place it in the same directory as the executable.\n\n" + "Error details: " + e + "\n\nPress any key to continue."); Console.ReadKey(true); System.Environment.Exit(1); } catch (System.UnauthorizedAccessException e) { Console.WriteLine("\nError: the file \"one\" can't be accessed.\n" + "Make sure that the file and the current folder are not in read only access.\n\n" + "Error details: " + e + "\n\nPress any key to continue."); Console.ReadKey(true); System.Environment.Exit(1); } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(true); System.Environment.Exit(1); } try { arcOriginalFiles = lst.TryOpen(originalFile); } catch (System.UnauthorizedAccessException e) { Console.WriteLine("\nError: the file \"one.lst\" can't be accessed.\n" + "Make sure that the file and the current folder are not in read only access.\n\n" + "Error details: " + e + "\n\nPress any key to continue."); Console.ReadKey(true); System.Environment.Exit(1); } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(true); System.Environment.Exit(1); } try { afsOriginalFiles = arcOriginalFiles.CreateFileSystem(); } catch (System.NullReferenceException e) { Console.WriteLine("\nError: the file \"one.lst\" was not found.\n" + "Make sure to place it in the same directory as the executable.\n\n" + "Error details: " + e + "\n\nPress any key to continue."); Console.ReadKey(true); System.Environment.Exit(1); } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(true); System.Environment.Exit(1); } List <Entry> originalFilesList = new List <Entry>(); originalFilesList = (List <Entry>)afsOriginalFiles.GetFiles(); int i = 0; foreach (Entry entry in originalFilesList) { String fileName = ""; //Updating the name of the file if (patchFilesList.ToArray().Length > i) { fileName = ((Entry)patchFilesList.ToArray()[i]).Name; //Remove the suffix of the name of the files if (fileName.Contains(suffix)) { fileName = fileName.Replace(suffix, ""); } } //Skip the bonus CGs if the user doesn't want them if (inputBonusCG.Substring(0, 1) == "2" && filesListToNotUpdate.Any(entry.Name.Contains)) { continue; } //Update if (patchFilesList.ToArray().Length > i && entry.Name.Equals(fileName)) { resultFilesList.Add((Entry)patchFilesList.ToArray()[i]); Console.WriteLine(fileName + " will be updated."); i++; } //Insert new file(s) and the current original file else if (patchFilesList.ToArray().Length > i && entry.Type.Equals(((Entry)patchFilesList.ToArray()[i]).Type) && String.Compare(entry.Name, fileName) > 0) { while (patchFilesList.ToArray().Length > i && entry.Type.Equals(((Entry)patchFilesList.ToArray()[i]).Type) && String.Compare(entry.Name, fileName) > 0 && !fileName.Equals("CGMODEAKMU.PNG")) { resultFilesList.Add((Entry)patchFilesList.ToArray()[i]); Console.WriteLine(fileName + " will be inserted."); i++; //Updating the name of the file if (patchFilesList.ToArray().Length > i) { fileName = ((Entry)patchFilesList.ToArray()[i]).Name; //Remove the suffix of the name of the files if (fileName.Contains(suffix)) { fileName = fileName.Replace(suffix, ""); } } } resultFilesList.Add(entry); } //Insert the current original file else { resultFilesList.Add(entry); } } //////////////////// //WRITING PART //////////////////// Console.WriteLine("Writing..."); var cp932 = Encodings.cp932.WithFatalFallback(); //cp932 is the encoding for the Japanese characters var nbFiles = resultFilesList.ToArray().Length; //count the number of files //The file one_TEMP will be written directly into binary BinaryWriter bw = null; bw = new BinaryWriter(File.Create("./one_TEMP.lst")); Boolean headerWritten = false; long offset = 0; //The key is always equal to 01 in hexa (at least for ONE), it's possible to change it without any impact but I don't see the point to do it var key = 0x01; var convertedKey = key; //The first operation takes the key, convert it into binary, move the bits to 8 positions towards the left and make a binary OR with the first key, I've put some examples //This allows the key to be on 32 bits instead of 8 (the program uses a lot of 32 bits functions) convertedKey |= convertedKey << 8; //1 => 257, 0001 => 0000 0001 0000 0001 convertedKey |= convertedKey << 16; //257 => 16 843 009 => 0001 0001 0001 0001 //This key is used to encrypt the SNX files, she's always equal to 02 //We only need the key to be on 8 bits so we don't do a conversion var keySNX = 0x02; //This part is used to initialize the variables used to read the one_TEMP file Stream stream = null; var output = PhysicalFileSystem.CreateFile("./one_TEMP"); //Loop that will treat each file, it's going to insert an entry into the one_TEMP.lst file and then insert it into the one_TEMP file afterwards foreach (Entry entry in resultFilesList) { //We start with the transformation of the data //Remove the suffix of the name of the files String fileName = entry.Name; if (fileName.Contains(suffix)) { fileName = fileName.Replace(suffix, ""); } int pointPosition = fileName.IndexOf("."); String extension = fileName.Substring(pointPosition + 1, fileName.Length - pointPosition - 1); byte[] bufferName = LstOpener.WriteName(fileName.Substring(0, pointPosition), 64, (byte)key, cp932); long fileSize = entry.Size ^ convertedKey; long convertedOffset = offset ^ convertedKey; offset += entry.Size; //Type is the only part that is not encrypted with the key int type = 0; if (extension.Equals("SNX")) { type = 1; } else if (extension.Equals("BMP")) { type = 2; } else if (extension.Equals("PNG")) { type = 3; } else if (extension.Equals("WAV")) { type = 4; } else if (extension.Equals("OGG")) { type = 5; } else { type = -1; } //Byte writing in the lst file //Writing of the header if (!headerWritten) { //The header corresponds to the 4 first bytes of the files, he indicates the number of files and the key (4th bytes) var header = nbFiles ^ convertedKey; bw.Write(header); headerWritten = true; } bw.Write((int)convertedOffset); bw.Write((int)fileSize); bw.Write(bufferName); bw.Write(type); //Creation of the file into the one file //These two conditions are used to determinate if the current file comes from the original files or the patch files if (afsOriginalFiles.FileExists(entry.Name)) { stream = arcOriginalFiles.OpenEntry(entry); } else if (afsPatchFiles.FileExists(entry.Name)) { stream = arcPatchFiles.OpenEntry(entry); } int byteTempo = 0; //The SNX files need to be written byte by byte, indeed, we need to transform them because they're encrypted in the one file with a XOR key 02 to make sure that nobody can read them if (type == 1) { while ((byteTempo = stream.ReadByte()) > -1) { byteTempo = byteTempo ^ keySNX; output.WriteByte((byte)byteTempo); //we directly wrote the bytes into the file without using the stream } } else { stream.CopyTo(output); } stream.Dispose(); } //The original Japanese version ends with 48 bytes corresponding to the end of a PNG file. //It's not the case for the English translation, it doesn't seem to have an impact in the game and it's very probably a mistake since the last file is also a PNG file (the value is duplicated). //However, I prefer to put it in order to have a faithful recreation of the file. if (inputLanguage.Substring(0, 1) == "1") { List <byte> listByteFinFichier = new List <byte> { 0xa4, 0x01, 0xcc, 0x9c, 0x72, 0x05, 0x0c, 0x0c, 0x33, 0x01, 0x47, 0x00, 0x8f, 0x07, 0xef, 0x9f, 0xce, 0xaa, 0x0a, 0x60, 0xb8, 0x6e, 0x5e, 0x0c, 0x7e, 0x0b, 0x30, 0x00, 0xf1, 0x70, 0xc4, 0x43, 0x75, 0x7e, 0x8f, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; foreach (byte b in listByteFinFichier) { output.WriteByte(b); } } bw.Close(); output.Close(); output.Dispose(); originalFile.Dispose(); patchFile.Dispose(); //At the end, we replace the original files with the files that we have created. File.SetAttributes("one", FileAttributes.Normal); File.SetAttributes("one.lst", FileAttributes.Normal); File.Delete("one"); File.Delete("one.lst"); File.Move("one_TEMP", "one"); File.Move("one_TEMP.lst", "one.lst"); Console.WriteLine("\nDone!"); Console.WriteLine("\nPress any key to continue."); Console.ReadKey(true); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var g00arc = (G00Archive)arc; return(new BinMemoryStream(g00arc.Bitmap, (int)entry.Offset, (int)entry.Size)); }
public async Task ListFileNamesTest(string filename) { using ArcFile arcFile = new ArcFile(filename); using TextWriter textWriter = new StreamWriter("log_arcnames.txt"); await arcFile.ForAll((entry, name) => textWriter.WriteLine(name)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var warc = arc as WarcFile; var wentry = entry as WarcEntry; if (null == warc || null == wentry || entry.Size < 8) { return(arc.File.CreateStream(entry.Offset, entry.Size)); } var enc_data = new byte[entry.Size]; if (entry.Size != arc.File.View.Read(entry.Offset, enc_data, 0, entry.Size)) { return(Stream.Null); } uint sig = LittleEndian.ToUInt32(enc_data, 0); uint unpacked_size = LittleEndian.ToUInt32(enc_data, 4); sig ^= (unpacked_size ^ 0x82AD82) & 0xffffff; if (0 != (wentry.Flags & 0x80000000u) && entry.Size > 8) // encrypted entry { warc.Decoder.Decrypt(enc_data, 8, entry.Size - 8); } if (warc.Decoder.SchemeVersion >= 2490) { warc.Decoder.DecryptExtra(enc_data, 8, entry.Size - 8, 0x202); } if (0 != (wentry.Flags & 0x20000000u) && entry.Size > 8) { warc.Decoder.Decrypt2(enc_data, 8, entry.Size - 8); } byte[] unpacked = enc_data; UnpackMethod unpack = null; switch (sig & 0xffffff) { case 0x314859: // 'YH1' unpack = UnpackYH1; break; case 0x4b5059: // 'YPK' unpack = UnpackYPK; break; case 0x5a4c59: // 'YLZ' unpack = UnpackYLZ; break; } if (null != unpack) { unpacked = new byte[unpacked_size]; unpack(enc_data, unpacked); if (0 != (wentry.Flags & 0x40000000)) { warc.Decoder.Decrypt2(unpacked, 0, (uint)unpacked.Length); } if (warc.Decoder.SchemeVersion >= 2490) { warc.Decoder.DecryptExtra(unpacked, 0, (uint)unpacked.Length, 0x204); } } return(new MemoryStream(unpacked)); }
void ExtractEntryAsIs(ArcFile arc, Entry entry) { using (var input = arc.OpenEntry(entry)) using (var output = CreateNewFile(entry.Name, true)) input.CopyTo(output); }