Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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));
            }
        }
Esempio n. 3
0
        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();
                }
            }
        }
Esempio n. 4
0
 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);
 }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
 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;
 }
Esempio n. 7
0
 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);
     }
 }
Esempio n. 8
0
 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);
 }
Esempio n. 9
0
 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);
 }
Esempio n. 10
0
 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);
 }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
 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);
 }
Esempio n. 13
0
 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);
     }
 }
Esempio n. 14
0
 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);
     }
 }
Esempio n. 15
0
 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);
     }
 }
Esempio n. 16
0
 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);
     }
 }
Esempio n. 17
0
 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);
 }
Esempio n. 18
0
 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);
     }
 }
Esempio n. 19
0
 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);
 }
Esempio n. 20
0
        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);
            }
        }
Esempio n. 21
0
 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;
     }
 }
Esempio n. 22
0
 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);
 }
Esempio n. 23
0
 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);
     }
 }
Esempio n. 24
0
 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;
 }
Esempio n. 25
0
        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));
        }
Esempio n. 26
0
        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);
            }
        }
Esempio n. 27
0
        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);
            }
        }
Esempio n. 28
0
 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());
     }
 }
Esempio n. 29
0
        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);
        }
Esempio n. 30
0
 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);
     }
 }
Esempio n. 31
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var parc = (PmxArchive)arc;

            return(new StreamRegion(parc.BaseStream, entry.Offset, entry.Size, true));
        }
Esempio n. 32
0

        
Esempio n. 33
0
        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();
                }
            }
        }
Esempio n. 34
0
        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));
            }
        }
Esempio n. 35
0

        
Esempio n. 36
0
 public override Stream OpenEntry(ArcFile arc, Entry entry)
 {
     return(((ZipEntry)entry).NativeEntry.Open());
 }
Esempio n. 37
0
 void CopyAmiEntry(ArcFile base_archive, Entry entry, Stream output)
 {
     using (var input = base_archive.File.CreateStream(entry.Offset, entry.Size))
         input.CopyTo(output);
 }
Esempio n. 38
0
 public async Task ArcFileCommuTest(string arcName, string outputXlsx)
 {
     using ArcFile arcFile = new ArcFile(arcName);
     await arcFile.ExtractCommusToXlsx(outputXlsx, true, progress);
 }
Esempio n. 39
0
        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);
        }
Esempio n. 40
0
 /// <summary>
 /// Perform necessary initialization specific to an archive being opened.
 /// </summary>
 public virtual void Init(ArcFile arc)
 {
 }
Esempio n. 41
0
        public override IImageDecoder OpenImage(ArcFile arc, Entry entry)
        {
            var input = arc.File.CreateStream(entry.Offset, entry.Size);

            return(new MngFrameDecoder(input));
        }
Esempio n. 42
0
        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;
            }
        }
Esempio n. 43
0
 public override Stream OpenEntry(ArcFile arc, Entry entry)
 {
     return(((CabEntry)entry).Info.OpenRead());
 }
Esempio n. 44
0
 public async Task ArcParameterIndividualTest(string arcName, string outputXlsx)
 {
     using ArcFile arcFile = new ArcFile(arcName);
     await arcFile.ExtractParameterToXlsx(outputXlsx, true, progress);
 }
Esempio n. 45
0
        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();
                }
            }
        }
Esempio n. 46
0
 //[DataRow("hdd.arc", "images/hdd_images")]
 public async Task ExtractAllImagesTest(string arcName, string outDir)
 {
     using ArcFile arcFile = new ArcFile(arcName);
     await arcFile.ExtractAllImages(outDir);
 }
Esempio n. 47
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var input = arc.File.CreateStream(entry.Offset, entry.Size);

            return(new XoredStream(input, 0x90));
        }
Esempio n. 48
0
 public async Task ExtractLyricsTest(string arcName, string outDir)
 {
     using ArcFile arcFile = new ArcFile(arcName);
     await arcFile.ExtractLyrics(outDir, true);
 }
Esempio n. 49
0
        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);
        }
Esempio n. 51
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var g00arc = (G00Archive)arc;

            return(new BinMemoryStream(g00arc.Bitmap, (int)entry.Offset, (int)entry.Size));
        }
Esempio n. 52
0
 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));
 }
Esempio n. 53
0
        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));
        }
Esempio n. 54
0
 void ExtractEntryAsIs(ArcFile arc, Entry entry)
 {
     using (var input = arc.OpenEntry(entry))
         using (var output = CreateNewFile(entry.Name, true))
             input.CopyTo(output);
 }