示例#1
0
        /**
         * Creates and returns a new FST Entry
         * @return
         */
        public static FSTEntry getRootFSTEntry()
        {
            FSTEntryParam param = new FSTEntryParam();

            param.isRoot = true;
            param.isDir  = true;
            return(new FSTEntry(param));
        }
示例#2
0
 public FSTEntry(FSTEntryParam fstParam)
 {
     this.filename = fstParam.Filename;
     this.path     = fstParam.Path;
     this.flags    = fstParam.Flags;
     this.parent   = fstParam.Parent;
     if (parent != null)
     {
         parent.Children.Add(this);
     }
     this.fileSize   = fstParam.FileSize;
     this.fileOffset = fstParam.FileOffset;
     this.content    = fstParam.Content;
     if (content != null)
     {
         content.addEntry(this);
     }
     this.isDir          = fstParam.isDir;
     this.isRoot         = fstParam.isRoot;
     this.isNotInPackage = fstParam.notInPackage;
     this.contentFSTID   = fstParam.ContentFSTID;
 }
示例#3
0
        public static void parseFST(FSTEntry rootEntry, byte[] fstSection, byte[] namesSection, Dictionary <int, Content> contentsByIndex,
                                    Dictionary <int, ContentFSTInfo> contentsFSTByIndex)
        {
            int totalEntries = Utils.SwapEndianness(BitConverter.ToInt32(fstSection, 0x08));

            int level = 0;

            int[]    LEntry      = new int[16];
            int[]    Entry       = new int[16];
            String[] pathStrings = new String[16];
            for (int i = 0; i < 16; i++)
            {
                pathStrings[i] = "";
            }

            Dictionary <int, FSTEntry> fstEntryToOffsetMap = new Dictionary <int, FSTEntry>();

            Entry[level]    = 0;
            LEntry[level++] = 0;

            fstEntryToOffsetMap.Add(0, rootEntry);

            int    lastlevel = level;
            String path      = "\\";

            FSTEntry last = null;

            for (int i = 1; i < totalEntries; i++)
            {
                int entryOffset = i;
                if (level > 0)
                {
                    while (LEntry[level - 1] == i)
                    {
                        level--;
                    }
                }

                byte[] curEntry = Arrays.copyOfRange(fstSection, i * 0x10, (i + 1) * 0x10);

                FSTEntryParam entryParam = new FSTEntryParam();

                if (lastlevel != level)
                {
                    path      = pathStrings[level] + getFullPath(level - 1, level, fstSection, namesSection, Entry);
                    lastlevel = level;
                }

                String filename = getName(curEntry, namesSection);

                long fileOffset = Utils.SwapEndianness(BitConverter.ToInt32(curEntry, 0x04));
                long fileSize   = (uint)Utils.SwapEndianness(BitConverter.ToInt32(curEntry, 0x08));

                short flags        = Utils.SwapEndianness(BitConverter.ToInt16(curEntry, 0x0C));
                short contentIndex = Utils.SwapEndianness(BitConverter.ToInt16(curEntry, 0x0E));

                if ((curEntry[0] & FSTEntry.FSTEntry_notInNUS) == FSTEntry.FSTEntry_notInNUS)
                {
                    entryParam.notInPackage = (true);
                }
                FSTEntry parent = null;
                if ((curEntry[0] & FSTEntry.FSTEntry_DIR) == FSTEntry.FSTEntry_DIR)
                {
                    entryParam.isDir = (true);
                    int parentOffset = (int)fileOffset;
                    int nextOffset   = (int)fileSize;

                    parent             = fstEntryToOffsetMap[parentOffset];
                    Entry[level]       = i;
                    LEntry[level++]    = nextOffset;
                    pathStrings[level] = path;

                    if (level > 15)
                    {
                        //MessageBox.Show("level > 15");
                        break;
                    }
                }
                else
                {
                    entryParam.FileOffset = (fileOffset << 5);

                    entryParam.FileSize = (fileSize);
                    parent = fstEntryToOffsetMap[(Entry[level - 1])];
                }

                entryParam.Flags    = (flags);
                entryParam.Filename = (filename);
                entryParam.Path     = (path);

                if (contentsByIndex != null)
                {
                    Content content = contentsByIndex[contentIndex];
                    if (content == null)
                    {
                        //MessageBox.Show("Content for FST Entry not found");
                    }
                    else
                    {
                        if (content.isHashed() && (content.getDecryptedFileSize() < (fileOffset << 5)))
                        { // TODO: Figure out how this works...
                            entryParam.FileOffset = (fileOffset);
                        }

                        entryParam.Content = (content);

                        ContentFSTInfo contentFSTInfo = contentsFSTByIndex[(int)contentIndex];
                        if (contentFSTInfo == null)
                        {
                            //MessageBox.Show("ContentFSTInfo for FST Entry not found");
                        }
                        else
                        {
                            content.contentFSTInfo = (contentFSTInfo);
                        }
                    }
                }

                entryParam.ContentFSTID = (contentIndex);
                entryParam.Parent       = (parent);

                FSTEntry entry = new FSTEntry(entryParam);
                last = entry;
                fstEntryToOffsetMap.Add(entryOffset, entry);
            }
        }