public override ArcFile TryOpen(ArcView file) { string lst_name = Path.ChangeExtension(file.Name, ".lst"); if (lst_name == file.Name || !VFS.FileExists(lst_name)) { return(null); } var lst_entry = VFS.FindFile(lst_name); int count = (int)(lst_entry.Size / 0x16); if (count > 0xffff || count * 0x16 != lst_entry.Size) { return(null); } using (var lst = VFS.OpenView(lst_entry)) { var dir = new List <Entry> (count); uint index_offset = 0; for (int i = 0; i < count; ++i) { string name = lst.View.ReadString(index_offset, 14); var entry = FormatCatalog.Instance.Create <Entry> (name); entry.Offset = lst.View.ReadUInt32(index_offset + 14); entry.Size = lst.View.ReadUInt32(index_offset + 18); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += 0x16; } return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".lay")) { return(null); } int tile_count = file.View.ReadInt32(0); int coord_count = file.View.ReadInt32(4); if (!IsSaneCount(tile_count) || !IsSaneCount(coord_count)) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name).TrimEnd('_'); var png_name = VFS.ChangeFileName(file.Name, base_name + ".png"); if (!VFS.FileExists(png_name)) { return(null); } ImageData image; var png_entry = VFS.FindFile(png_name); using (var decoder = VFS.OpenImage(png_entry)) image = decoder.Image; using (var input = file.CreateStream()) using (var index = new BinaryReader(input)) { input.Position = 8; var dir = new List <Entry> (tile_count); for (int i = 0; i < tile_count; ++i) { uint id = index.ReadUInt32(); int first = index.ReadInt32(); int count = index.ReadInt32(); var name = string.Format("{0}#{1:X8}", base_name, id); var entry = new LayEntry { Name = name, Type = "image", Offset = 0, Id = id, First = first, Count = count }; dir.Add(entry); } var tiles = new List <LayCoord> (coord_count); for (int i = 0; i < coord_count; ++i) { var tile = new LayCoord(); tile.TargetX = index.ReadSingle() + 1; tile.TargetY = index.ReadSingle() + 1; tile.SourceX = index.ReadSingle() - 1; tile.SourceY = index.ReadSingle() - 1; tiles.Add(tile); } return(new LayArchive(file, this, dir, image.Bitmap, tiles)); } }
public override ArcFile TryOpen(ArcView file) { var arc_list = new List <Entry>(); long max_offset = file.MaxOffset; for (int i = 1; i < 100; ++i) { var part_name = Path.ChangeExtension(file.Name, string.Format("a{0:D02}", i)); if (!VFS.FileExists(part_name)) { break; } var part = VFS.FindFile(part_name); arc_list.Add(part); max_offset += part.Size; } uint index_length = file.View.ReadUInt32(8); uint data_offset = file.View.ReadUInt32(0x10); using (var zindex = file.CreateStream(0x20, index_length)) using (var uindex = new ZLibStream(zindex, CompressionMode.Decompress)) using (var index = new BinaryStream(uindex, file.Name)) { var buffer = new byte[500]; var dir = new List <Entry>(); while (index.PeekByte() != -1) { int entry_length = index.ReadInt32(); if (entry_length <= 528) { return(null); } bool is_deleted = index.ReadUInt32() != 0; var entry = new PackedEntry(); entry.Offset = index.ReadInt64() + data_offset; index.ReadUInt32(); entry.Size = index.ReadUInt32(); entry.UnpackedSize = index.ReadUInt32(); entry.IsPacked = entry.Size != entry.UnpackedSize; index.Read(buffer, 0, 500); int name_length = index.Read(buffer, 0, entry_length - 528); if (!is_deleted && entry.CheckPlacement(max_offset)) { entry.Name = Encoding.Unicode.GetString(buffer, 0, name_length); entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); dir.Add(entry); } } return(new Mpf2Archive(file, this, dir, arc_list)); } }
public override ArcFile TryOpen(ArcView file) { string index_name = Path.ChangeExtension(file.Name, ".dll"); if (index_name == file.Name || !VFS.FileExists(index_name)) { return(null); } var index_entry = VFS.FindFile(index_name); if (index_entry.Size < 12) { return(null); } int count = file.View.ReadInt32(0); if (!IsSaneCount(count) || (count & 0xFFFF) == 0x5A4D) // 'MZ' { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); using (var idx = VFS.OpenView(index_entry)) { var dir = new List <Entry> (count); uint index_offset = 4; int i = 0; uint last_offset = 3; while (index_offset + 8 <= idx.MaxOffset) { uint offset = idx.View.ReadUInt32(index_offset); if (offset <= last_offset) { return(null); } var name = string.Format("{0}#{1:D5}", base_name, i++); var entry = AutoEntry.Create(file, offset, name); entry.Size = idx.View.ReadUInt32(index_offset + 4); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); last_offset = offset; index_offset += 8; } return(new ArcFile(file, this, dir)); } }
DirectoryViewModel GetNewViewModel(string path) { if (!string.IsNullOrEmpty(path)) { if (!VFS.IsVirtual) { path = Path.GetFullPath(path); } var entry = VFS.FindFile(path); if (!(entry is SubDirEntry)) { SetBusyState(); } VFS.ChDir(entry); } return(new DirectoryViewModel(VFS.FullPath, VFS.GetFiles(), VFS.IsVirtual)); }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".vpk")) { return(null); } var vtb_name = Path.ChangeExtension(file.Name, "vtb"); if (!VFS.FileExists(vtb_name)) { return(null); } var vtb_entry = VFS.FindFile(vtb_name); int count = (int)(vtb_entry.Size / 0x0C) - 1; if (!IsSaneCount(count)) { return(null); } using (var vtb = VFS.OpenView(vtb_entry)) { vtb.View.Reserve(0, (uint)vtb.MaxOffset); uint index_offset = 0; uint next_offset = vtb.View.ReadUInt32(8); var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { string name = vtb.View.ReadString(index_offset, 8) + ".vaw"; var entry = FormatCatalog.Instance.Create <Entry> (name); entry.Offset = next_offset; index_offset += 0xC; next_offset = vtb.View.ReadUInt32(index_offset + 8); entry.Size = next_offset - (uint)entry.Offset; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new ArcFile(file, this, dir)); } }
public override IImageDecoder OpenImage(ArcFile arc, Entry entry) { var input = arc.OpenBinaryEntry(entry); int length = (int)(input.Length - 0x10); if ((length & 3) != 0) { return(ImageFormatDecoder.Create(input)); } uint width = input.ReadUInt32(); uint height = input.ReadUInt32(); int buf_width = input.ReadInt32(); int buf_height = input.ReadInt32(); var info = new ImageMetaData { Width = width, Height = height, BPP = 32 }; if (DefaultVisualMap.Value.ContainsKey(entry.Name)) { var diff_info = DefaultVisualMap.Value[entry.Name]; if (VFS.FileExists(diff_info.BaseFileName)) { var base_entry = VFS.FindFile(diff_info.BaseFileName); using (var visbase = VFS.OpenImage(base_entry)) { var base_decoder = visbase as Gx4ImageDecoder; if (base_decoder != null) { info.OffsetX = diff_info.PosX; info.OffsetY = diff_info.PosY; var pixels = base_decoder.ReadPixels(); return(new Gx4OverlayDecoder(pixels, base_decoder.Info, input, info)); } } } } return(new Gx4ImageDecoder(input, info)); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(0, "EPK ")) { return(null); } uint index_size = file.View.ReadUInt32(4) - 0x20; int count = file.View.ReadInt32(0x18); if (!IsSaneCount(count) || index_size >= file.MaxOffset) { return(null); } uint index_offset = 0x20; if (index_size > file.View.Reserve(index_offset, index_size)) { return(null); } var arc_list = new List <Entry>(); var arc_dir = VFS.GetDirectoryName(file.Name); var arc_name = Path.GetFileNameWithoutExtension(file.Name); for (int i = 1; i < 10; ++i) { var part_name = string.Format("{0}.e{1:D02}", arc_name, i); part_name = VFS.CombinePath(arc_dir, part_name); if (!VFS.FileExists(part_name)) { break; } arc_list.Add(VFS.FindFile(part_name)); } var name_buffer = new byte[0x40]; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { uint name_offset = file.View.ReadUInt32(index_offset + 8); int name_length = file.View.ReadInt32(name_offset); if (name_length <= 0 || name_length >= index_size) { return(null); } if (name_length > name_buffer.Length) { name_buffer = new byte[name_length]; } file.View.Read(name_offset + 4, name_buffer, 0, (uint)name_length); for (int j = 0; j < name_length; ++j) { name_buffer[j] ^= 0xFF; } var name = Encodings.cp932.GetString(name_buffer, 0, name_length); var entry = FormatCatalog.Instance.Create <EpkEntry> (name); entry.Offset = file.View.ReadInt64(index_offset + 0x10); entry.Size = file.View.ReadUInt32(index_offset + 0x18); dir.Add(entry); index_offset += 0x28; } var arc_set = new List <ArcView> (arc_list.Count); try { long max_offset = file.MaxOffset; var bounds = new List <long> (arc_list.Count + 1); bounds.Add(max_offset); foreach (var arc_entry in arc_list) { var arc_file = VFS.OpenView(arc_entry); arc_set.Add(arc_file); max_offset += arc_file.MaxOffset; bounds.Add(max_offset); } foreach (EpkEntry entry in dir) { if (!entry.CheckPlacement(max_offset)) { return(null); } entry.ArcNumber = bounds.FindIndex(x => x > entry.Offset); if (entry.ArcNumber > 0) { entry.Offset -= bounds[entry.ArcNumber - 1]; } } var arc = new EpkArchive(file, this, dir, arc_set); arc_set = null; return(arc); } finally { if (arc_set != null) { foreach (var arc in arc_set) { arc.Dispose(); } } } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".paz")) { return(null); } uint signature = file.View.ReadUInt32(0); // XXX encryption is queried for every .paz file var scheme = QueryEncryption(file.Name, signature); uint start_offset = scheme.Version > 0 ? 0x20u : 0u; uint index_size = file.View.ReadUInt32(start_offset); start_offset += 4; byte xor_key = (byte)(index_size >> 24); if (xor_key != 0) { index_size ^= (uint)(xor_key << 24 | xor_key << 16 | xor_key << 8 | xor_key); } if (0 != (index_size & 7) || index_size + start_offset >= file.MaxOffset) { return(null); } var arc_list = new List <Entry>(); var arc_dir = VFS.GetDirectoryName(file.Name); long max_offset = file.MaxOffset; for (char suffix = 'A'; suffix <= 'Z'; ++suffix) { var part_name = VFS.CombinePath(arc_dir, file.Name + suffix); if (!VFS.FileExists(part_name)) { break; } var part = VFS.FindFile(part_name); arc_list.Add(part); max_offset += part.Size; } var arc_name = Path.GetFileNameWithoutExtension(file.Name).ToLowerInvariant(); bool is_audio = AudioPazNames.Contains(arc_name); bool is_video = VideoPazNames.Contains(arc_name); Stream input = file.CreateStream(start_offset, index_size); byte[] video_key = null; List <Entry> dir; try { if (xor_key != 0) { input = new XoredStream(input, xor_key); } var enc = new Blowfish(scheme.ArcKeys[arc_name].IndexKey); input = new InputCryptoStream(input, enc.CreateDecryptor()); using (var index = new ArcView.Reader(input)) { int count = index.ReadInt32(); if (!IsSaneCount(count)) { return(null); } if (is_video) { video_key = index.ReadBytes(0x100); } dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = index.BaseStream.ReadCString(); var entry = FormatCatalog.Instance.Create <PazEntry> (name); entry.Offset = index.ReadInt64(); entry.UnpackedSize = index.ReadUInt32(); entry.Size = index.ReadUInt32(); entry.AlignedSize = index.ReadUInt32(); if (!entry.CheckPlacement(max_offset)) { return(null); } entry.IsPacked = index.ReadInt32() != 0; if (string.IsNullOrEmpty(entry.Type) && is_audio) { entry.Type = "audio"; } if (scheme.Version > 0) { string password = ""; if (!entry.IsPacked && scheme.TypeKeys != null) { password = scheme.GetTypePassword(name, is_audio); } if (!string.IsNullOrEmpty(password) || is_video) { password = string.Format("{0} {1:X08} {2}", name.ToLowerInvariant(), entry.UnpackedSize, password); entry.Key = Encodings.cp932.GetBytes(password); } } dir.Add(entry); } } } finally { input.Dispose(); } List <ArcView> parts = null; if (arc_list.Count > 0) { parts = new List <ArcView> (arc_list.Count); try { foreach (var arc_entry in arc_list) { var arc_file = VFS.OpenView(arc_entry); parts.Add(arc_file); } } catch { foreach (var part in parts) { part.Dispose(); } throw; } } if (is_video) { if (scheme.Version < 1) { var table = new byte[0x100]; for (int i = 0; i < 0x100; ++i) { table[video_key[i]] = (byte)i; } video_key = table; } return(new MovPazArchive(file, this, dir, scheme.Version, xor_key, video_key, parts)); } return(new PazArchive(file, this, dir, scheme.Version, xor_key, scheme.ArcKeys[arc_name].DataKey, parts)); }
public override ArcFile TryOpen(ArcView file) { if (file.Name.HasExtension(".idx")) { return(null); } string idx_name = Path.ChangeExtension(file.Name, ".idx"); if (!VFS.FileExists(idx_name)) { return(null); } var idx_entry = VFS.FindFile(idx_name); if (idx_entry.Size > 0xfffff || idx_entry.Size < 10000) { return(null); } byte[] index; using (var idx = VFS.OpenView(idx_entry)) index = DecryptIndex(idx); int index_offset = 0; int entry_size = index.Length / 10000; if (entry_size > 40) { entry_size = 40; } bool long_offsets = 40 == entry_size; int name_size = long_offsets ? 0x18 : 0x14; long first_offset = LittleEndian.ToUInt32(index, name_size); bool has_scripts = false; var dir = new List <Entry>(); while (index_offset < index.Length) { if (0 == index[index_offset]) { break; } var name = Binary.GetCString(index, index_offset, name_size); index_offset += name_size; var entry = FormatCatalog.Instance.Create <Entry> (name); if (name.HasExtension("dat")) { entry.Type = "script"; has_scripts = true; } if (long_offsets) { entry.Offset = LittleEndian.ToInt64(index, index_offset) - first_offset; entry.Size = LittleEndian.ToUInt32(index, index_offset + 8); index_offset += 0x10; } else { entry.Offset = LittleEndian.ToUInt32(index, index_offset) - first_offset; entry.Size = LittleEndian.ToUInt32(index, index_offset + 4); index_offset += 8; } if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } if (0 == dir.Count) { return(null); } if (dir[0].Name.HasExtension("gr")) // CG archive { var rng = DetectEncryptionScheme(file, dir[0]); return(new EaglsArchive(file, this, dir, new CgEncryption(rng))); } else if (has_scripts) { var enc = QueryEncryption(); if (enc != null) { return(new EaglsArchive(file, this, dir, enc)); } } return(new ArcFile(file, this, dir)); }
public override ImageMetaData ReadMetaData(Stream stream) { var tex = VFS.FindFile("tex"); if (!(tex is SubDirEntry)) { return(null); } using (var reader = new StreamReader(stream, Encoding.UTF8, false, 2048, true)) { reader.ReadLine(); // skip signature string line = reader.ReadLine(); if (null == line) { return(null); } var match = pair_re.Match(line); if (!match.Success) { return(null); } uint width = Convert.ToUInt16(match.Groups[1].Value); uint height = Convert.ToUInt16(match.Groups[2].Value); line = reader.ReadLine(); if (null == line) { return(null); } int count = Convert.ToInt16(line); if (0 == count) { return(null); } var list = new List <IEnumerable <DziTile> > (count); for (int i = 0; i < count; ++i) { line = reader.ReadLine(); if (null == line) { return(null); } match = pair_re.Match(line); if (!match.Success) { return(null); } int block_w = Convert.ToUInt16(match.Groups[1].Value); int block_h = Convert.ToUInt16(match.Groups[2].Value); var tiles = new List <DziTile> (block_w * block_h); int y = 0; for (int j = 0; j < block_h; ++j) { int x = 0; line = reader.ReadLine(); if (null == line) { return(null); } line = line.TrimEnd(); foreach (var file in line.Split(',')) { if (!string.IsNullOrEmpty(file)) { var filename = VFS.CombinePath(tex.Name, file); tiles.Add(new DziTile { X = x, Y = y, FileName = filename }); } x += 256; } y += 256; } list.Add(tiles); } return(new DziMetaData { Width = width, Height = height, BPP = 32, Tiles = list, }); } }
public override ArcFile TryOpen(ArcView file) { string idx_name = Path.ChangeExtension(file.Name, ".idx"); if (file.Name.Equals(idx_name, StringComparison.InvariantCultureIgnoreCase) || !VFS.FileExists(idx_name)) { return(null); } var idx_entry = VFS.FindFile(idx_name); if (idx_entry.Size > 0xfffff || idx_entry.Size < 10000) { return(null); } byte[] index; using (var idx = VFS.OpenView(idx_entry)) index = DecryptIndex(idx); int index_offset = 0; int entry_size = index.Length / 10000; bool long_offsets = 40 == entry_size; int name_size = long_offsets ? 0x18 : 0x14; long first_offset = LittleEndian.ToUInt32(index, name_size); var dir = new List <Entry>(); while (index_offset < index.Length) { if (0 == index[index_offset]) { break; } var name = Binary.GetCString(index, index_offset, name_size); index_offset += name_size; var entry = FormatCatalog.Instance.Create <Entry> (name); if (name.EndsWith(".dat", StringComparison.InvariantCultureIgnoreCase)) { entry.Type = "script"; } if (long_offsets) { entry.Offset = LittleEndian.ToInt64(index, index_offset) - first_offset; entry.Size = LittleEndian.ToUInt32(index, index_offset + 8); index_offset += 0x10; } else { entry.Offset = LittleEndian.ToUInt32(index, index_offset) - first_offset; entry.Size = LittleEndian.ToUInt32(index, index_offset + 4); index_offset += 8; } if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } if (0 == dir.Count) { return(null); } if (dir[0].Name.EndsWith(".gr", StringComparison.InvariantCultureIgnoreCase)) // CG archive { return(new CgArchive(file, this, dir)); } else { return(new ArcFile(file, this, dir)); } }