示例#1
0
        /// <summary>
        /// Reads a DBPF archive from a stream.
        /// </summary>
        /// <param name="stream">The stream to read from.</param>
        public void Read(Stream stream)
        {
            groupID         = Hash.GroupHash(Path.GetFileNameWithoutExtension(fname));
            m_EntryByFullID = new Dictionary <int, DBPFEntry>();
            m_EntriesList   = new List <DBPFEntry>();

            var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN);

            m_Reader = io;
            this.Io  = io;

            var magic = io.ReadCString(4);

            if (magic != "DBPF")
            {
                throw new Exception("Not a DBPF file");
            }

            var majorVersion = io.ReadUInt32();
            var minorVersion = io.ReadUInt32();
            var version      = majorVersion + (((double)minorVersion) / 10.0);

            /** Unknown, set to 0 **/
            io.Skip(12);
            if (version <= 1.2)
            {
                this.DateCreated  = io.ReadInt32();
                this.DateModified = io.ReadInt32();
            }

            if (version < 2.0)
            {
                IndexMajorVersion = io.ReadUInt32();
            }

            NumEntries = io.ReadUInt32();
            uint indexOffset = 0;

            if (version < 2.0)
            {
                indexOffset = io.ReadUInt32();
            }
            var indexSize = io.ReadUInt32();

            //uint indexMinor = 0;
            if (version < 2.0)
            {
                var trashEntryCount  = io.ReadUInt32();
                var trashIndexOffset = io.ReadUInt32();
                var trashIndexSize   = io.ReadUInt32();
                IndexMinorVersion = io.ReadUInt32();
            }
            else if (version == 2.0)
            {
                IndexMinorVersion = io.ReadUInt32();
                indexOffset       = io.ReadUInt32();
                io.Skip(4);
            }

            /** Padding **/
            io.Skip(32);

            io.Seek(SeekOrigin.Begin, indexOffset);
            var nameMaps = new List <DBPFEntry>();
            var rcols    = new List <DBPFEntry>();

            for (int i = 0; i < NumEntries; i++)
            {
                var entry = new DBPFEntry();
                entry.file    = this;
                entry.TypeID  = io.ReadUInt32();
                entry.GroupID = io.ReadUInt32();
                if (entry.GroupID == 0xFFFFFFFF)
                {
                    entry.GroupID = groupID;
                }
                entry.InstanceID = io.ReadUInt32();
                if (IndexMinorVersion >= 2)
                {
                    entry.InstanceID2 = io.ReadUInt32();
                }
                entry.FileOffset = io.ReadUInt32();
                entry.FileSize   = io.ReadUInt32();
                var id     = Hash.TGIHash(entry.InstanceID, entry.TypeID, entry.GroupID);
                var fullID = Hash.TGIRHash(entry.InstanceID, entry.InstanceID2, entry.TypeID, entry.GroupID);
                m_EntryByID[id]         = entry;
                m_EntryByFullID[fullID] = entry;
                if (!m_EntriesByType.ContainsKey(entry.TypeID))
                {
                    m_EntriesByType.Add(entry.TypeID, new List <DBPFEntry>());
                }
                m_EntriesByType[entry.TypeID].Add(entry);
            }
            var dirEntry = GetItemByFullID(Hash.TGIRHash((uint)0x286B1F03, (uint)0x00000000, (uint)0xE86B1EEF, (uint)0xE86B1EEF));

            if (dirEntry != null)
            {
                hasCompression = true;
                DIRFile.Read(this, dirEntry);
            }
            foreach (var element in nameMaps)
            {
                var b1g     = GetEntry(element);
                var stream1 = new MemoryStream(b1g);
                var read    = new IoBuffer(stream1);
                read.ByteOrder = ByteOrder.LITTLE_ENDIAN;
                var numNames = read.ReadUInt32();
                for (var j = 0; j < numNames; j++)
                {
                    var gID = read.ReadUInt32();
                    if (gID == 0xFFFFFFFF)
                    {
                        gID = groupID;
                    }
                    var       iID        = read.ReadUInt32();
                    var       nameLength = read.ReadUInt32();
                    var       fileNam    = read.ReadCString((int)nameLength).ToLower();
                    DBPFEntry hash       = null;
                    hash = GetEntryByID(Hash.TGIHash(iID, element.InstanceID, gID));
                    var gNam = "##0x" + gID.ToString("x8") + "!" + fileNam;

                    if (hash != null)
                    {
                        m_EntryByName[fileNam] = hash;
                        m_EntryByName[gNam]    = hash;
                    }
                }
                read.Dispose();
                stream1.Dispose();
            }
        }
示例#2
0
        /// <summary>
        /// Reads a DBPF archive from a stream.
        /// </summary>
        /// <param name="stream">The stream to read from.</param>
        public void Read(Stream stream, bool global = false, bool isDownload = false)
        {
            groupID         = Hash.GroupHash(Path.GetFileNameWithoutExtension(fname));
            m_EntryByFullID = new Dictionary <int, DBPFEntry>();
            m_EntriesList   = new List <DBPFEntry>();

            var io = IoBuffer.FromStream(stream, ByteOrder.LITTLE_ENDIAN);

            m_Reader = io;
            this.Io  = io;

            var magic = io.ReadCString(4);

            if (magic != "DBPF")
            {
                throw new Exception("Not a DBPF file");
            }

            var majorVersion = io.ReadUInt32();
            var minorVersion = io.ReadUInt32();
            var version      = majorVersion + (((double)minorVersion) / 10.0);

            /** Unknown, set to 0 **/
            io.Skip(12);
            if (version <= 1.2)
            {
                this.DateCreated  = io.ReadInt32();
                this.DateModified = io.ReadInt32();
            }

            if (version < 2.0)
            {
                IndexMajorVersion = io.ReadUInt32();
            }

            NumEntries = io.ReadUInt32();
            uint indexOffset = 0;

            if (version < 2.0)
            {
                indexOffset = io.ReadUInt32();
            }
            var indexSize = io.ReadUInt32();

            //uint indexMinor = 0;
            if (version < 2.0)
            {
                var trashEntryCount  = io.ReadUInt32();
                var trashIndexOffset = io.ReadUInt32();
                var trashIndexSize   = io.ReadUInt32();
                IndexMinorVersion = io.ReadUInt32();
            }
            else if (version == 2.0)
            {
                IndexMinorVersion = io.ReadUInt32();
                indexOffset       = io.ReadUInt32();
                io.Skip(4);
            }

            /** Padding **/
            io.Skip(32);

            io.Seek(SeekOrigin.Begin, indexOffset);
            var nameMaps = new List <DBPFEntry>();
            var rcols    = new List <DBPFEntry>();

            for (int i = 0; i < NumEntries; i++)
            {
                var entry = new DBPFEntry();
                entry.file    = this;
                entry.TypeID  = io.ReadUInt32();
                entry.GroupID = io.ReadUInt32();
                if (entry.GroupID == 0xFFFFFFFF)
                {
                    entry.GroupID = groupID;
                }
                entry.InstanceID = io.ReadUInt32();
                if (IndexMinorVersion >= 2)
                {
                    entry.InstanceID2 = io.ReadUInt32();
                }
                entry.FileOffset = io.ReadUInt32();
                entry.FileSize   = io.ReadUInt32();

                //Debug.Log("Found type: " + entry.TypeID.ToString("x"));
                //Debug.Log("Instance: " + entry.InstanceID.ToString("x"));

                //m_EntriesList.Add(entry);
                //var id = new EntryRef(entry.InstanceID, entry.InstanceID2, entry.TypeID);
                var id     = Hash.TGIHash(entry.InstanceID, entry.TypeID, entry.GroupID);
                var fullID = Hash.TGIRHash(entry.InstanceID, entry.InstanceID2, entry.TypeID, entry.GroupID);
                //ulong id = (((ulong)entry.InstanceID) << 32) + (ulong)entry.InstanceID2 + (ulong)entry.TypeID;

                // if (!m_EntryByID.ContainsKey(id))
                m_EntryByID[id]         = entry;
                m_EntryByFullID[fullID] = entry;

                if (entry.TypeID == 0x4E6D6150)
                {
                    nameMaps.Add(entry);
                }
                if (RCOLFile.RCOLTypeIDs.IndexOf(entry.TypeID) >= 0)
                {
                    rcols.Add(entry);
                }
                //if (!m_EntryByFullID.ContainsKey(fullID))

                /*
                 *  m_EntryByFullID[fullID] = entry;*/
                if (!m_EntriesByType.ContainsKey(entry.TypeID))
                {
                    m_EntriesByType.Add(entry.TypeID, new List <DBPFEntry>());
                }
                m_EntriesByType[entry.TypeID].Add(entry);
                entry.global = global;
                if (Environment.entryByFullID.ContainsKey(fullID))
                {
                    entry.global = false;
                }
                if (entry.global)
                {
                    Environment.entryByID[id]         = entry;
                    Environment.entryByFullID[fullID] = entry;
                    if (!Environment.entryByType.ContainsKey(entry.TypeID))
                    {
                        Environment.entryByType.Add(entry.TypeID, new List <DBPFEntry>());
                    }
                    Environment.entryByType[entry.TypeID].Add(entry);
                }
            }
            //var dirEntry = GetItemByID((((ulong)0x286B1F03) << 32) + (ulong)0x00000000 + (ulong)0xE86B1EEF);

            var dirEntry = GetItemByFullID(Hash.TGIRHash((uint)0x286B1F03, (uint)0x00000000, (uint)0xE86B1EEF, (uint)0xE86B1EEF));

            if (dirEntry != null)
            {
                DIRFile.Read(this, dirEntry);
                //DIR = new DIRFile(this, dirEntry);
            }
            foreach (var element in nameMaps)
            {
                var b1g     = GetEntry(element);
                var stream1 = new MemoryStream(b1g);
                var read    = new IoBuffer(stream1);
                read.ByteOrder = ByteOrder.LITTLE_ENDIAN;
                var numNames = read.ReadUInt32();
                for (var j = 0; j < numNames; j++)
                {
                    var gID = read.ReadUInt32();
                    if (gID == 0xFFFFFFFF)
                    {
                        gID = groupID;
                    }
                    var       iID        = read.ReadUInt32();
                    var       nameLength = read.ReadUInt32();
                    var       fileNam    = read.ReadCString((int)nameLength).ToLower();
                    DBPFEntry hash       = null;

                    /*
                     * var gotGlobal = false;
                     *
                     * if (global)
                     * {
                     *  hash = Environment.GetEntryTGI(Hash.TGIHash(iID, element.InstanceID, gID));
                     *  gotGlobal = true;
                     * }
                     * else*/
                    hash = GetEntryByID(Hash.TGIHash(iID, element.InstanceID, gID));
                    //Debug.Log(filenam);
                    var gNam = "##0x" + gID.ToString("x8") + "!" + fileNam;

                    if (hash != null)
                    {
                        //Debug.Log("Can't find instance (InstanceID: " + iID.ToString("X") + ", TypeID: " + element.InstanceID.ToString("X") + ", GroupID: " + gID.ToString("X") + ") for name '" + fileNam + "/" + gNam + "'(Package:"+fname+")");*/

                        /*
                         * if (!gotGlobal)
                         * {*/
                        m_EntryByName[fileNam] = hash;
                        m_EntryByName[gNam]    = hash;
                        //}


                        if (hash.global)
                        {
                            Environment.entryByName[fileNam] = hash;
                            Environment.entryByName[gNam]    = hash;
                        }
                    }

                    /*
                     * else
                     *  Debug.Log("Can't find instance (InstanceID: " + iID.ToString("X") + ", TypeID: " + element.InstanceID.ToString("X") + ", GroupID: " + gID.ToString("X") + ") for name '" + fileNam + "/" + gNam + "'(Package:" + fname + ")");*/
                }
                read.Dispose();
                stream1.Dispose();
            }

            if (nameMaps.Count == 0 || isDownload)
            {
                foreach (var element in rcols)
                {
                    var ent = GetEntry(element);
                    var gId = "0x" + element.GroupID.ToString("x8");
                    var nam = "";
                    if (element.TypeID == 0xE519C933)
                    {
                        try
                        {
                            nam = RCOLFile.GetCRESName(ent).ToLower();
                        }catch (Exception e)
                        {
                        }
                    }
                    else if (element.TypeID == 0x7BA3838C)
                    {
                        try
                        {
                            nam = RCOLFile.GetGMNDName(ent).ToLower();
                        }
                        catch (Exception e)
                        {
                        }
                    }
                    else
                    {
                        try
                        {
                            nam = RCOLFile.GetName(ent).ToLower();
                        }
                        catch (Exception e)
                        {
                            //Uhmmm... Fail silently!
                        }
                    }
                    var gNam = "##" + gId + "!" + nam;
                    m_EntryByName[nam]  = element;
                    m_EntryByName[gNam] = element;
                    if (element.global)
                    {
                        Environment.entryByName[nam]  = element;
                        Environment.entryByName[gNam] = element;
                    }
                }
            }
        }