示例#1
0
        public byte[] ExtractResource(TAHEntry entry)
        {
            //data読み込み長さ
            //-4はdata書き出し長さ格納領域 (UInt32) を減じている
            UInt32 input_length = entry.length - 4;

            //data読み込みバッファ
            byte[] data_input = new byte[input_length];
            UInt32 output_length;

            reader.BaseStream.Position = entry.offset;

            //data書き出し長さ
            output_length = reader.ReadUInt32();
            data_input    = reader.ReadBytes((int)input_length);
            //-- data読み込み(復号前)完了! --

            //data書き出しバッファ
            byte[] data_output = new byte[output_length];

            TAHCryption.crypt(ref data_input, input_length, output_length);
            Decompression.infrate(ref data_input, input_length, ref data_output, output_length);
            //-- data復号完了! --

            return(data_output);
        }
示例#2
0
        /* TAH Procedures*/

        public void extract_TAH_directory()
        {
            Entries = null;

            UInt32 arc_size = (UInt32)reader.BaseStream.Length;

            byte[] magic = reader.ReadBytes(4);

            if (magic[0] != (byte)'T' || magic[1] != (byte)'A' || magic[2] != (byte)'H' || magic[3] != (byte)'2')
            {
                throw new Exception("File is not TAH");
            }

            Header tah_header;

            tah_header.index_entry_count = reader.ReadUInt32();
            tah_header.version           = reader.ReadUInt32();
            tah_header.reserved          = reader.ReadUInt32();

            UInt32 index_buffer_size = tah_header.index_entry_count * 8; //sizeof(index_entry) == 8

            Entries = new TAHEntry[tah_header.index_entry_count];

            for (int i = 0; i < tah_header.index_entry_count; i++)
            {
                Entries[i] = new TAHEntry();

                Entries[i].hash_code = reader.ReadUInt32();
                Entries[i].offset    = reader.ReadUInt32();
            }

            UInt32 output_length = reader.ReadUInt32();

            //entry情報の読み出し長さ
            UInt32 input_length = Entries[0].offset - /*sizeof(Header)*/ 16 - index_buffer_size;

            //entry情報の読み出しバッファ
            byte[] data_input = new byte[input_length];

            data_input = reader.ReadBytes((int)input_length);
            //-- entry情報の読み込み完了! --

            byte[] output_data = new byte[output_length];

            TAHCryption.crypt(ref data_input, input_length, output_length);
            Decompression.infrate(ref data_input, input_length, ref output_data, output_length);
            //-- entry情報の復号完了! --

            build_TAHEntries(output_data, arc_size);
        }
示例#3
0
        public void build_TAHEntries(byte[] str_file_path, UInt32 arc_size)
        {
            using (BinaryReader br = new BinaryReader(new MemoryStream(str_file_path)))
            {
                try
                {
                    string path = "";
                    while (true)
                    {
                        string name = br.ReadCString();
                        if (name.EndsWith("/"))
                        {
                            path = name;
                        }
                        else
                        {
                            string   file_name = path + name;
                            TAHEntry ent       = FindTAHEntryByHash(CalcHash(file_name));
                            if (ent != null)
                            {
                                ent.file_name = file_name;
                            }
                        }
                    }
                }
                catch (EndOfStreamException)
                {
                }
            }

            ext_file_list external_files;

            build_ext_file_list(out external_files);

            for (UInt32 i = 0; i < Entries.Length; i++)
            {
                //file_nameが見つからなかった場合
                if (Entries[i].file_name == null)
                {
                    //names.txt を検索
                    int pos = -1;
                    if (external_files.files != null)
                    {
                        pos = Array.BinarySearch(external_files.hashkeys, Entries[i].hash_name);
                    }
                    if (pos < 0) // not found
                    {
                        //ファイル名は <hash>にする
                        Entries[i].file_name = string.Format("{0:X8}", Entries[i].hash_name);
                        //file_nameが見つからなかったflag on
                        Entries[i].flag ^= 0x1;
                    }
                    else
                    {
                        Entries[i].file_name = external_files.files[pos];
                    }
                }
            }

            for (UInt32 i = 0; i < Entries.Length - 1; i++)
            {
                //data読み込み長さを設定
                //読み込み長さは現在entryオフセットと次のentryオフセットとの差である
                Entries[i].length = Entries[i + 1].offset - Entries[i].offset;
            }
            //最終entry data読み込み長さを設定
            Entries[Entries.Length - 1].length = arc_size - Entries[Entries.Length - 1].offset;
        }