public override ArcFile TryOpen(ArcView file) { var name = Path.GetFileName(file.Name); if (!NamePattern.IsMatch(name)) { return(null); } var match = NamePattern.Match(name); int name_id = 1; var num_str = match.Groups["num"].Value; if (!string.IsNullOrEmpty(num_str)) { name_id = Int32.Parse(num_str); } if (name_id < 1) { return(null); } ArcView index = file; try { if (name_id != 1) { string index_name; if (file.Name.HasExtension(".dat")) { index_name = VFS.ChangeFileName(file.Name, "0001.dat"); } else { index_name = VFS.ChangeFileName(file.Name, "data"); } if (!VFS.FileExists(index_name)) { return(null); } index = VFS.OpenView(index_name); } var dir = ReadIndex(index, name_id, file.MaxOffset); if (null == dir || 0 == dir.Count) { return(null); } return(new ArcFile(file, this, dir)); } finally { if (index != file) { index.Dispose(); } } }
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) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } var pac_name = Path.GetFileNameWithoutExtension(file.Name); int pac_num; if (!Int32.TryParse(pac_name, out pac_num)) { return(null); } var hdr_name = string.Format("{0:D3}.dat", pac_num - 1); hdr_name = VFS.ChangeFileName(file.Name, hdr_name); if (!VFS.FileExists(hdr_name)) { return(null); } using (var index = VFS.OpenBinaryStream(hdr_name)) { var header = index.ReadHeader(8); if (!header.AsciiEqual("\x89HDR")) { return(null); } if (header.ToInt32(4) != count) { return(null); } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = index.ReadCString(0x10); var entry = FormatCatalog.Instance.Create <Entry> (name); entry.Size = index.ReadUInt32(); entry.Offset = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new ArcFile(file, this, dir)); } }
IEnumerable <string> GetPaletteNames(string filename) { var base_name = Path.GetFileNameWithoutExtension(filename); yield return(VFS.ChangeFileName(filename, base_name + ".pal")); if (base_name.Length > 3) { base_name = base_name.Substring(0, 3); yield return(VFS.ChangeFileName(filename, base_name + ".pal")); } yield return(VFS.ChangeFileName(filename, base_name + "_2.pal")); yield return(VFS.ChangeFileName(filename, base_name + "_1.pal")); }
public override ImageData Read(IBinaryStream file, ImageMetaData info) { file.Position = 12; var pixels = file.ReadBytes((int)info.Width * (int)info.Height); var format = PixelFormats.Gray8; BitmapPalette palette = null; var palette_name = VFS.ChangeFileName(file.Name, "data.act"); if (VFS.FileExists(palette_name)) { using (var pal_file = VFS.OpenStream(palette_name)) palette = ReadPalette(pal_file, 0x100, PaletteFormat.Rgb); format = PixelFormats.Indexed8; } return(ImageData.Create(info, format, palette, pixels)); }
BitmapSource BlendBaseLine(BitmapSource overlay, GdtMetaData meta) { string base_name = VFS.ChangeFileName(meta.FileName, meta.BaseLine); if (!VFS.FileExists(base_name)) { base_name += ".gdt"; if (!VFS.FileExists(base_name)) { return(overlay); } } using (var base_file = VFS.OpenBinaryStream(base_name)) { var base_info = ReadMetaData(base_file) as GdtMetaData; if (null == base_info) { return(overlay); } var base_image = ReadBitmapSource(base_file, base_info); if (base_image.Format.BitsPerPixel < 24) { base_image = new FormatConvertedBitmap(base_image, PixelFormats.Bgr32, null, 0); } var canvas = new WriteableBitmap(base_image); int canvas_bpp = canvas.Format.BitsPerPixel; if (canvas_bpp != overlay.Format.BitsPerPixel) { overlay = new FormatConvertedBitmap(overlay, canvas.Format, null, 0); } canvas.Lock(); unsafe { byte *buffer = (byte *)canvas.BackBuffer; int canvas_stride = canvas.BackBufferStride; int canvas_size = canvas_stride * canvas.PixelHeight; int overlay_stride = (overlay.PixelWidth * canvas_bpp + 7) / 8; int overlay_size = overlay_stride * overlay.PixelHeight; int pos = meta.OffsetY * canvas_stride + meta.OffsetX * canvas_bpp / 8; overlay.CopyPixels(Int32Rect.Empty, (IntPtr)(buffer + pos), canvas_size - pos, canvas_stride); } var rect = new Int32Rect(meta.OffsetX, meta.OffsetY, overlay.PixelWidth, overlay.PixelHeight); canvas.AddDirtyRect(rect); canvas.Unlock(); return(canvas); } }
internal BitmapPalette ReadDefaultPalette(string filename) { var pal_name = Path.ChangeExtension(filename, ".pal"); if (!VFS.FileExists(pal_name)) { pal_name = VFS.ChangeFileName(filename, DefaultPaletteName); } if (!VFS.FileExists(pal_name)) { return(null); } using (var input = VFS.OpenStream(pal_name)) { return(ReadPalette(input, 0x100, PaletteFormat.Rgb)); } }
public override ArcFile TryOpen(ArcView file) { var name = Path.GetFileName(file.Name); if (!NamePattern.IsMatch(name)) { return(null); } var match = NamePattern.Match(name); int name_id = Int32.Parse(match.Groups[1].Value); if (name_id < 1) { return(null); } ArcView index = file; try { if (name_id != 1) { var index_name = VFS.ChangeFileName(file.Name, "0001.dat"); if (!VFS.FileExists(index_name)) { return(null); } index = VFS.OpenView(index_name); } var dir = ReadIndex(index, name_id, file.MaxOffset); if (null == dir || 0 == dir.Count) { return(null); } return(new ArcFile(file, this, dir)); } finally { if (index != file) { index.Dispose(); } } }
public override ImageData Read(IBinaryStream file, ImageMetaData info) { var meta = (RctMetaData)info; var pixels = ReadPixelsData(file, meta); if (ApplyMask.Get <bool>()) { var mask_name = Path.GetFileNameWithoutExtension(meta.FileName) + "_.rc8"; mask_name = VFS.ChangeFileName(meta.FileName, mask_name); if (VFS.FileExists(mask_name)) { try { return(ApplyMaskToImage(meta, pixels, mask_name)); } catch { /* ignore mask read errors */ } } } return(ImageData.Create(meta, PixelFormats.Bgr24, null, pixels, (int)meta.Width * 3)); }
public override ArcFile TryOpen(ArcView file) { if (file.MaxOffset > uint.MaxValue || !VFS.IsPathEqualsToFileName(file.Name, "ArchPac.dat")) { return(null); } foreach (var scheme in KnownSchemes.Values.Where(s => s.IndexOffset < file.MaxOffset).OrderBy(s => s.IndexOffset)) { var dir = ReadIndex(file, scheme.IndexOffset, file.MaxOffset); if (dir != null) { if (scheme.EventMap != null) { return(new SeraphArchive(file, this, dir, scheme)); } else { return(new ArcFile(file, this, dir)); } } } var scnpac_name = VFS.ChangeFileName(file.Name, "ScnPac.dat"); if (!VFS.FileExists(scnpac_name)) { return(null); } using (var scnpac = VFS.OpenView(scnpac_name)) { uint first_offset = scnpac.View.ReadUInt32(4); uint index_offset = scnpac.View.ReadUInt32(first_offset - 4); var dir = ReadIndex(scnpac, index_offset, file.MaxOffset); if (dir != null) { return(new ArcFile(file, this, dir)); } } return(null); }
public override ArcFile TryOpen(ArcView file) { var base_name = Path.GetFileName(file.Name); var sx_name = base_name.Substring(0, 4) + "(00).sx"; sx_name = VFS.ChangeFileName(file.Name, sx_name); if (!VFS.FileExists(sx_name) || file.Name.Equals(sx_name, StringComparison.InvariantCultureIgnoreCase)) { return(null); } byte[] index_data; using (var sx = VFS.OpenView(sx_name)) { if (sx.MaxOffset <= 0x10) { return(null); } if (!sx.View.AsciiEqual(0, "SSXXDEFL")) { return(null); } int key = Binary.BigEndian(sx.View.ReadInt32(8)); int length = (int)(sx.MaxOffset - 0x10); var index_packed = sx.View.ReadBytes(0x10, (uint)length); long lkey = (long)key + length; lkey = key ^ (961 * lkey - 124789) ^ DefaultKey; uint key_lo = (uint)lkey; uint key_hi = (uint)(lkey >> 32) ^ 0x2E6; DecryptData(index_packed, key_lo, key_hi); index_data = UnpackZstd(index_packed); } using (var index = new BinMemoryStream(index_data)) { var reader = new SxIndexDeserializer(index, file.MaxOffset); var dir = reader.Deserialize(); return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".dat")) { return(null); } var idx_name = VFS.ChangeFileName(file.Name, "index.idx"); if (!VFS.FileExists(idx_name)) { return(null); } using (var index = VFS.OpenBinaryStream(idx_name)) { var dir = new List <Entry>(); while (index.PeekByte() != -1) { var name = index.ReadCString(0x34); if (string.IsNullOrEmpty(name)) { break; } var entry = Create <Entry> (name); entry.Offset = index.ReadUInt32(); entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } if (0 == dir.Count) { return(null); } return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".dat") || VFS.IsPathEqualsToFileName(file.Name, "00000000.dat")) { return(null); } var index_name = VFS.ChangeFileName(file.Name, "00000000.dat"); if (!VFS.FileExists(index_name)) { return(null); } var arc_name = Path.GetFileName(file.Name); using (var index = VFS.OpenView(index_name)) { var dir = ReadIndex(index, arc_name, file.MaxOffset); if (null == dir) { return(null); } return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".dat")) { return(null); } var arc_name = Path.GetFileName(file.Name); var match = IndexNameRe.Match(arc_name); if (!match.Success) { return(null); } var base_name = match.Groups[2].Value; base_name = VFS.ChangeFileName(file.Name, base_name); var index_name = base_name + ".pcg"; if (!VFS.FileExists(index_name)) { index_name = base_name + ".spf"; if (!VFS.FileExists(index_name)) { return(null); } } arc_name = match.Groups[1].Value; using (var index = VFS.OpenView(index_name)) { int parts_count = index.View.ReadInt32(0); int count = index.View.ReadInt32(4); if (parts_count > 10 || !IsSaneCount(count)) { return(null); } int entry_size = (int)(index.MaxOffset - 0x198) / count; if (entry_size < 0x30) { return(null); } int first_index = -1, last_index = -1; for (int i = 0; i < parts_count; ++i) { int name_pos = 8 + i * 0x20; var name = index.View.ReadString(name_pos, 0x20); if (name == arc_name) { int first_index_pos = 0x148 + i * 4; int last_index_pos = 0x170 + i * 4; first_index = index.View.ReadInt32(first_index_pos); last_index = index.View.ReadInt32(last_index_pos); break; } } if (first_index < 0 || first_index >= last_index || last_index > count) { return(null); } uint name_size = entry_size >= 0x48 ? 0x40u : 0x20u; int index_offset = 0x198 + entry_size * first_index; var dir = new List <Entry> (last_index - first_index); for (int i = first_index; i < last_index; ++i) { var name = index.View.ReadString(index_offset, name_size); var entry = FormatCatalog.Instance.Create <Entry> (name); entry.Size = index.View.ReadUInt32(index_offset + name_size); entry.Offset = index.View.ReadUInt32(index_offset + name_size + 4); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); index_offset += entry_size; } return(new ArcFile(file, this, dir)); } }
ArchiveKey FindArchiveKey(string arc_name) { // look for "start.ps3" in the same directory as an archive var start_name = VFS.ChangeFileName(arc_name, "start.ps3"); if (!VFS.FileExists(start_name)) { return(null); } byte[] start_data; using (var start = VFS.OpenView(start_name)) { if (!start.View.AsciiEqual(0, "PS2A")) { return(null); } start_data = start.View.ReadBytes(0, (uint)start.MaxOffset); } arc_name = Path.GetFileName(arc_name); start_data = UnpackPs2(start_data); int table_count = start_data.ToInt32(0x10); int strings_offset = 0x30 + table_count * 4 + start_data.ToInt32(0x14); int strings_size = start_data.ToInt32(0x1C); if (strings_offset < 0x30 || strings_offset + strings_size > start_data.Length) { return(null); } // search strings table for archive name int string_pos = strings_offset; int strings_end = strings_offset + strings_size; int arc_id = -1; while (string_pos < strings_end) { int end_pos = Array.IndexOf <byte> (start_data, 0, string_pos); if (-1 == end_pos) { end_pos = strings_offset + strings_size; } if (end_pos != string_pos) { var text = Encodings.cp932.GetString(start_data, string_pos, end_pos - string_pos); if (VFS.IsPathEqualsToFileName(text, arc_name)) { arc_id = string_pos - strings_offset; break; } } string_pos = end_pos + 1; } if (-1 == arc_id) { return(null); } // search bytecode for a reference to archive name found above var id_bytes = new byte[4]; LittleEndian.Pack(arc_id, id_bytes, 0); for (int data_pos = 0x30 + table_count * 4; data_pos + 4 <= strings_offset; ++data_pos) { if (start_data[data_pos + 0] == id_bytes[0] && start_data[data_pos + 1] == id_bytes[1] && start_data[data_pos + 2] == id_bytes[2] && start_data[data_pos + 3] == id_bytes[3]) { if (start_data[data_pos - 0x33] == 2 && start_data[data_pos - 0x32] == 0 && start_data[data_pos - 0x31] == 1) { return(new ArchiveKey { IndexDirKey = start_data.ToUInt32(data_pos - 0x0C), IndexEntryKey = start_data.ToUInt32(data_pos - 0x18), EntryDataKey1 = start_data.ToUInt32(data_pos - 0x24), EntryDataKey2 = start_data.ToUInt32(data_pos - 0x30), }); } } } return(null); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count) || VFS.IsPathEqualsToFileName(file.Name, "00.mpk")) { return(null); } var list_name = VFS.ChangeFileName(file.Name, "00.mpk"); List <string> filelist; if (VFS.FileExists(list_name)) { using (var s = VFS.OpenStream(list_name)) using (var xs = new XoredStream(s, 0xA)) using (var reader = new StreamReader(xs, Encodings.cp932)) { filelist = new List <string> (count); string filename; while ((filename = reader.ReadLine()) != null) { filelist.Add(filename); } } } else { var base_name = Path.GetFileNameWithoutExtension(file.Name); filelist = Enumerable.Range(0, count).Select(x => string.Format("{0}#{1:D4}", base_name, x)).ToList(); } bool has_sizes = file.View.ReadByte(3) != 'P'; uint index_offset = 8; uint record_size = has_sizes ? 8u : 4u; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = FormatCatalog.Instance.Create <Entry> (filelist[i]); entry.Offset = file.View.ReadUInt32(index_offset); if (has_sizes) { entry.Size = file.View.ReadUInt32(index_offset + 4); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } } else if (entry.Offset > file.MaxOffset) { return(null); } dir.Add(entry); index_offset += record_size; } if (!has_sizes) { for (int i = 1; i < count; ++i) { dir[i - 1].Size = (uint)(dir[i].Offset - dir[i - 1].Offset); } dir[dir.Count - 1].Size = (uint)(file.MaxOffset - dir[dir.Count - 1].Offset); } return(new ArcFile(file, this, dir)); }