Exemplo n.º 1
0
        /// <summary>
        /// Checks whether a file is a U8 file or not.
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static bool IsU8(byte[] file)
        {
            if (Lz77.IsLz77Compressed(file))
            {
                byte[] partOfFile = new byte[(file.Length > 2000) ? 2000 : file.Length];

                for (int i = 0; i < partOfFile.Length; i++)
                {
                    partOfFile[i] = file[i];
                }

                Lz77 l = new Lz77();
                partOfFile = l.Decompress(partOfFile);

                return(IsU8(partOfFile));
            }
            else
            {
                Headers.HeaderType h = Headers.DetectHeader(file);
                return(Shared.Swap(BitConverter.ToUInt32(file, (int)h)) == 0x55AA382D);
            }
        }
Exemplo n.º 2
0
        private void parseU8(Stream u8File)
        {
            fireDebug("Pasing U8 File...");

            u8Header    = new U8_Header();
            rootNode    = new U8_Node();
            u8Nodes     = new List <U8_Node>();
            stringTable = new List <string>();
            data        = new List <byte[]>();

            fireDebug("   Detecting Header...");
            headerType = Headers.DetectHeader(u8File);
            Headers.HeaderType tempType = headerType;

            fireDebug("    -> {0}", headerType.ToString());

            if (headerType == Headers.HeaderType.IMD5)
            {
                fireDebug("   Reading IMD5 Header...");
                header = Headers.IMD5.Load(u8File);

                byte[] file = new byte[u8File.Length];
                u8File.Read(file, 0, file.Length);

                MD5    m       = MD5.Create();
                byte[] newHash = m.ComputeHash(file, (int)headerType, (int)u8File.Length - (int)headerType);
                m.Clear();

                if (!Shared.CompareByteArrays(newHash, ((Headers.IMD5)header).Hash))
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("Hashes of IMD5 header and file do not match! The content might be corrupted!"));
                }
            }
            else if (headerType == Headers.HeaderType.IMET || headerType == Headers.HeaderType.ShortIMET)
            {
                fireDebug("   Reading IMET Header...");
                header = Headers.IMET.Load(u8File);

                if (!((Headers.IMET)header).HashesMatch)
                {
                    fireDebug(@"/!\ /!\ /!\ Hashes do not match /!\ /!\ /!\");
                    fireWarning(string.Format("The hash stored in the IMET header doesn't match the headers hash! The header and/or file might be corrupted!"));
                }
            }

            fireDebug("   Checking for Lz77 Compression...");
            if (Lz77.IsLz77Compressed(u8File))
            {
                fireDebug("    -> Lz77 Compression Found...");
                fireDebug("   Decompressing U8 Data...");

                Lz77   l = new Lz77();
                Stream decompressedFile = l.Decompress(u8File);

                tempType = Headers.DetectHeader(decompressedFile);
                u8File   = decompressedFile;

                lz77 = true;
            }

            u8File.Seek((int)tempType, SeekOrigin.Begin);
            byte[] temp = new byte[4];

            //Read U8 Header
            fireDebug("   Reading U8 Header: Magic... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.U8Magic)
            {
                fireDebug("    -> Invalid Magic!"); throw new Exception("U8 Header: Invalid Magic!");
            }

            fireDebug("   Reading U8 Header: Offset to Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != u8Header.OffsetToRootNode)
            {
                fireDebug("    -> Invalid Offset to Rootnode"); throw new Exception("U8 Header: Invalid Offset to Rootnode!");
            }

            fireDebug("   Reading U8 Header: Header Size... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.HeaderSize = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            fireDebug("   Reading U8 Header: Offset to Data... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            u8Header.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Seek(16, SeekOrigin.Current);

            //Read Rootnode
            fireDebug("   Reading Rootnode... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
            u8File.Read(temp, 0, 4);
            rootNode.Type         = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
            rootNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

            u8File.Read(temp, 0, 4);
            rootNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            u8File.Read(temp, 0, 4);
            rootNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

            int stringTablePosition = (int)((int)tempType + u8Header.OffsetToRootNode + rootNode.SizeOfData * 12);
            int nodePosition        = (int)u8File.Position;

            //Read Nodes
            for (int i = 0; i < rootNode.SizeOfData - 1; i++)
            {
                fireDebug("   Reading Node #{1} of {2}... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper(), i + 1, rootNode.SizeOfData - 1);
                fireProgress((int)((i + 1) * 100 / (rootNode.SizeOfData - 1)));

                U8_Node tempNode = new U8_Node();
                string  tempName = string.Empty;
                byte[]  tempData = new byte[0];

                //Read Node Entry
                u8File.Seek(nodePosition, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Entry... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                u8File.Read(temp, 0, 4);
                tempNode.Type         = (U8_NodeType)Shared.Swap(BitConverter.ToUInt16(temp, 0));
                tempNode.OffsetToName = Shared.Swap(BitConverter.ToUInt16(temp, 2));

                u8File.Read(temp, 0, 4);
                tempNode.OffsetToData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                u8File.Read(temp, 0, 4);
                tempNode.SizeOfData = Shared.Swap(BitConverter.ToUInt32(temp, 0));

                nodePosition = (int)u8File.Position;

                fireDebug("        -> {0}", tempNode.Type.ToString());

                //Read Node Name
                u8File.Seek(stringTablePosition + tempNode.OffsetToName, SeekOrigin.Begin);

                fireDebug("    -> Reading Node Name... (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());
                for (;;)
                {
                    char tempChar = (char)u8File.ReadByte();
                    if (tempChar == 0x00)
                    {
                        break;
                    }

                    tempName += tempChar;

                    if (tempName.Length > 255)
                    {
                        break;
                    }
                }

                fireDebug("        -> {0}", tempName);

                //Read Node Data
                if (tempNode.Type == U8_NodeType.File)
                {
                    u8File.Seek((int)tempType + tempNode.OffsetToData, SeekOrigin.Begin);

                    fireDebug("    -> Reading Node Data (Offset: 0x{0})", u8File.Position.ToString("x8").ToUpper());

                    tempData = new byte[tempNode.SizeOfData];
                    u8File.Read(tempData, 0, tempData.Length);
                }

                if (tempName.ToLower() == "icon.bin")
                {
                    iconSize = getRealSize(tempData);
                }
                else if (tempName.ToLower() == "banner.bin")
                {
                    bannerSize = getRealSize(tempData);
                }
                else if (tempName.ToLower() == "sound.bin")
                {
                    soundSize = getRealSize(tempData);
                }

                u8Nodes.Add(tempNode);
                stringTable.Add(tempName);
                data.Add(tempData);
            }

            fireDebug("Pasing U8 File Finished...");
        }
Exemplo n.º 3
0
        private Stream compress(Stream inFile)
        {
            if (Lz77.IsLz77Compressed(inFile))
            {
                return(inFile);
            }
            inFile.Seek(0, SeekOrigin.Begin);

            int textSize = 0;
            int codeSize = 0;

            int i, c, r, s, length, lastMatchLength, codeBufferPointer, mask;

            int[] codeBuffer = new int[17];

            uint         fileSize = ((Convert.ToUInt32(inFile.Length)) << 8) + 0x10;
            MemoryStream outFile  = new MemoryStream();

            outFile.Write(BitConverter.GetBytes(Shared.Swap(lz77Magic)), 0, 4);
            outFile.Write(BitConverter.GetBytes(fileSize), 0, 4);

            InitTree();
            codeBuffer[0]     = 0;
            codeBufferPointer = 1;
            mask = 0x80;
            s    = 0;
            r    = N - F;

            for (i = s; i < r; i++)
            {
                textBuffer[i] = 0xffff;
            }

            for (length = 0; length < F && (c = (int)inFile.ReadByte()) != -1; length++)
            {
                textBuffer[r + length] = (ushort)c;
            }

            if ((textSize = length) == 0)
            {
                return(inFile);
            }

            for (i = 1; i <= F; i++)
            {
                InsertNode(r - i);
            }
            InsertNode(r);

            do
            {
                if (matchLength > length)
                {
                    matchLength = length;
                }

                if (matchLength <= threshold)
                {
                    matchLength = 1;
                    codeBuffer[codeBufferPointer++] = textBuffer[r];
                }
                else
                {
                    codeBuffer[0] |= mask;

                    codeBuffer[codeBufferPointer++] = (char)
                                                      (((r - matchPosition - 1) >> 8) & 0x0f) |
                                                      ((matchLength - (threshold + 1)) << 4);

                    codeBuffer[codeBufferPointer++] = (char)((r - matchPosition - 1) & 0xff);
                }

                if ((mask >>= 1) == 0)
                {
                    for (i = 0; i < codeBufferPointer; i++)
                    {
                        outFile.WriteByte((byte)codeBuffer[i]);
                    }

                    codeSize     += codeBufferPointer;
                    codeBuffer[0] = 0; codeBufferPointer = 1;
                    mask          = 0x80;
                }

                lastMatchLength = matchLength;
                for (i = 0; i < lastMatchLength && (c = (int)inFile.ReadByte()) != -1; i++)
                {
                    DeleteNode(s);

                    textBuffer[s] = (ushort)c;
                    if (s < F - 1)
                    {
                        textBuffer[s + N] = (ushort)c;
                    }
                    s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);

                    InsertNode(r);
                }

                while (i++ < lastMatchLength)
                {
                    DeleteNode(s);

                    s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
                    if (--length != 0)
                    {
                        InsertNode(r);
                    }
                }
            } while (length > 0);


            if (codeBufferPointer > 1)
            {
                for (i = 0; i < codeBufferPointer; i++)
                {
                    outFile.WriteByte((byte)codeBuffer[i]);
                }
                codeSize += codeBufferPointer;
            }

            if (codeSize % 4 != 0)
            {
                for (i = 0; i < 4 - (codeSize % 4); i++)
                {
                    outFile.WriteByte(0x00);
                }
            }

            return(outFile);
        }
Exemplo n.º 4
0
        private Stream decompress(Stream inFile)
        {
            if (!Lz77.IsLz77Compressed(inFile))
            {
                return(inFile);
            }
            inFile.Seek(0, SeekOrigin.Begin);

            int  i, j, k, r, c, z;
            uint flags, decompressedSize, currentSize = 0;

            Headers.HeaderType h = Headers.DetectHeader(inFile);

            byte[] temp = new byte[8];
            inFile.Seek((int)h, SeekOrigin.Begin);
            inFile.Read(temp, 0, 8);

            if (Shared.Swap(BitConverter.ToUInt32(temp, 0)) != lz77Magic)
            {
                inFile.Dispose(); throw new Exception("Invaild Magic!");
            }
            if (temp[4] != 0x10)
            {
                inFile.Dispose(); throw new Exception("Unsupported Compression Type!");
            }

            decompressedSize = (BitConverter.ToUInt32(temp, 4)) >> 8;

            for (i = 0; i < N - F; i++)
            {
                textBuffer[i] = 0xdf;
            }
            r = N - F; flags = 7; z = 7;

            MemoryStream outFile = new MemoryStream();

            while (true)
            {
                flags <<= 1;
                z++;

                if (z == 8)
                {
                    if ((c = inFile.ReadByte()) == -1)
                    {
                        break;
                    }

                    flags = (uint)c;
                    z     = 0;
                }

                if ((flags & 0x80) == 0)
                {
                    if ((c = inFile.ReadByte()) == inFile.Length - 1)
                    {
                        break;
                    }
                    if (currentSize < decompressedSize)
                    {
                        outFile.WriteByte((byte)c);
                    }

                    textBuffer[r++] = (byte)c;
                    r &= (N - 1);
                    currentSize++;
                }
                else
                {
                    if ((i = inFile.ReadByte()) == -1)
                    {
                        break;
                    }
                    if ((j = inFile.ReadByte()) == -1)
                    {
                        break;
                    }

                    j = j | ((i << 8) & 0xf00);
                    i = ((i >> 4) & 0x0f) + threshold;
                    for (k = 0; k <= i; k++)
                    {
                        c = textBuffer[(r - j - 1) & (N - 1)];
                        if (currentSize < decompressedSize)
                        {
                            outFile.WriteByte((byte)c);
                        }
                        textBuffer[r++] = (byte)c; r &= (N - 1); currentSize++;
                    }
                }
            }

            return(outFile);
        }