LoadMulPath() 공개 정적인 메소드

Fills MulPath with Files.Directory
public static LoadMulPath ( ) : void
리턴 void
예제 #1
0
 /// <summary>
 /// ReReads Art.mul
 /// </summary>
 public static void Reload()
 {
     Files.ReLoadDirectory();
     Files.LoadMulPath();
     m_FileIndex = new FileIndex("Artidx.mul", "Art.mul", 0x13FDC, 4);
     m_Cache     = new Bitmap[GetIdxLength()];
     m_Removed   = new bool[GetIdxLength()];
     m_patched.Clear();
     Modified = false;
 }
예제 #2
0
        /// <summary>
        /// ReReads gumpart
        /// </summary>
        public static void Reload()
        {
            try
            {
                Files.ReLoadDirectory();
                Files.LoadMulPath();
                m_FileIndex = new FileIndex("Gumpidx.mul", "Gumpart.mul", 0x10000, 12);
                m_Cache     = new Bitmap[m_FileIndex.Index.Length];
                m_Removed   = new bool[m_FileIndex.Index.Length];
            }
            catch
            {
                m_FileIndex = null;
                m_Cache     = new Bitmap[0xFFFF];
                m_Removed   = new bool[0xFFFF];
            }

            m_PixelBuffer  = null;
            m_StreamBuffer = null;
            m_ColorTable   = null;
            m_patched.Clear();
        }
예제 #3
0
        public FileIndex(string idxFile, string mulFile, int file)
        {
            string idxPath = null;

            MulPath = null;
            if (Files.MulPath == null)
            {
                Files.LoadMulPath();
            }
            if (Files.MulPath.Count > 0)
            {
                idxPath = Files.MulPath[idxFile.ToLower()];
                MulPath = Files.MulPath[mulFile.ToLower()];
                if (String.IsNullOrEmpty(idxPath))
                {
                    idxPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(idxPath)))
                    {
                        idxPath = Path.Combine(Files.RootDir, idxPath);
                    }
                    if (!File.Exists(idxPath))
                    {
                        idxPath = null;
                    }
                }
                if (String.IsNullOrEmpty(MulPath))
                {
                    MulPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(MulPath)))
                    {
                        MulPath = Path.Combine(Files.RootDir, MulPath);
                    }
                    if (!File.Exists(MulPath))
                    {
                        MulPath = null;
                    }
                }
            }

            if ((idxPath != null) && (MulPath != null))
            {
                using (FileStream index = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    int count = (int)(index.Length / 12);
                    IdxLength = index.Length;
                    Index     = new Entry3D[count];
                    GCHandle gc     = GCHandle.Alloc(Index, GCHandleType.Pinned);
                    byte[]   buffer = new byte[index.Length];
                    index.Read(buffer, 0, (int)index.Length);
                    Marshal.Copy(buffer, 0, gc.AddrOfPinnedObject(), (int)index.Length);
                    gc.Free();
                }
            }
            else
            {
                Stream = null;
                Index  = new Entry3D[1];
                return;
            }
            Entry5D[] patches = Verdata.Patches;

            if (file > -1)
            {
                for (int i = 0; i < patches.Length; ++i)
                {
                    Entry5D patch = patches[i];

                    if (patch.file == file && patch.index >= 0 && patch.index < Index.Length)
                    {
                        Index[patch.index].lookup = patch.lookup;
                        Index[patch.index].length = patch.length | (1 << 31);
                        Index[patch.index].extra  = patch.extra;
                    }
                }
            }
        }
예제 #4
0
        public FileIndex(string idxFile, string mulFile, string uopFile, int length, int file, string uopEntryExtension, int idxLength, bool hasExtra)
        {
            Index = new Entry3D[length];

            string idxPath = null;

            MulPath = null;
            string uopPath = null;

            if (Files.MulPath == null)
            {
                Files.LoadMulPath();
            }

            if (Files.MulPath.Count > 0)
            {
                idxPath = Files.MulPath[idxFile.ToLower()];
                MulPath = Files.MulPath[mulFile.ToLower()];

                if (!String.IsNullOrEmpty(uopFile) && Files.MulPath.ContainsKey(uopFile.ToLower()))
                {
                    uopPath = Files.MulPath[uopFile.ToLower()];
                }

                if (String.IsNullOrEmpty(idxPath))
                {
                    idxPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(idxPath)))
                    {
                        idxPath = Path.Combine(Files.RootDir, idxPath);
                    }

                    if (!File.Exists(idxPath))
                    {
                        idxPath = null;
                    }
                }

                if (String.IsNullOrEmpty(MulPath))
                {
                    MulPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(MulPath)))
                    {
                        MulPath = Path.Combine(Files.RootDir, MulPath);
                    }

                    if (!File.Exists(MulPath))
                    {
                        MulPath = null;
                    }
                }

                if (String.IsNullOrEmpty(uopPath))
                {
                    uopPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(uopPath)))
                    {
                        uopPath = Path.Combine(Files.RootDir, uopPath);
                    }

                    if (!File.Exists(uopPath))
                    {
                        uopPath = null;
                    }
                    else
                    {
                        MulPath = uopPath;
                    }
                }
            }

            /* UOP files support code, written by Wyatt (c) www.ruosi.org
             * idxLength variable was added for compatibility with legacy code for art (see art.cs)
             * At the moment the only UOP file having entries with extra field is gumpartlegacy.uop,
             * and it's two dwords in the beginning of the entry.
             * It's possible that UOP can include some entries with unknown hash: not really unknown for me, but
             * not useful for reading legacy entries. That's why i removed unknown hash exception throwing from this code
             */
            if (MulPath != null && MulPath.EndsWith(".uop"))
            {
                using (var index = new FileStream(MulPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Write | FileShare.Delete);

                    var fi         = new FileInfo(MulPath);
                    var uopPattern = fi.Name.Replace(fi.Extension, "").ToLowerInvariant();

                    using (var br = new BinaryReader(Stream))
                    {
                        br.BaseStream.Seek(0, SeekOrigin.Begin);

                        if (br.ReadInt32() != 0x50594D)
                        {
                            throw new ArgumentException("Bad UOP file.");
                        }

                        br.ReadInt64();                         // version + signature
                        var nextBlock = br.ReadInt64();
                        br.ReadInt32();                         // block capacity
                        var count = br.ReadInt32();

                        if (idxLength > 0)
                        {
                            IdxLength = idxLength * 12;
                        }

                        var hashes = new Dictionary <ulong, int>();

                        for (var i = 0; i < length; i++)
                        {
                            var entryName = String.Format("build/{0}/{1:D8}{2}", uopPattern, i, uopEntryExtension);
                            var hash      = HashFileName(entryName);

                            if (!hashes.ContainsKey(hash))
                            {
                                hashes.Add(hash, i);
                            }
                        }

                        br.BaseStream.Seek(nextBlock, SeekOrigin.Begin);

                        do
                        {
                            var filesCount = br.ReadInt32();
                            nextBlock = br.ReadInt64();

                            for (var i = 0; i < filesCount; i++)
                            {
                                var offset             = br.ReadInt64();
                                var headerLength       = br.ReadInt32();
                                var compressedLength   = br.ReadInt32();
                                var decompressedLength = br.ReadInt32();
                                var hash = br.ReadUInt64();
                                br.ReadUInt32();                                 // Adler32
                                var flag = br.ReadInt16();

                                var entryLength = flag == 1 ? compressedLength : decompressedLength;

                                if (offset == 0)
                                {
                                    continue;
                                }

                                if (hashes.TryGetValue(hash, out var idx))
                                {
                                    if (idx < 0 || idx > Index.Length)
                                    {
                                        throw new IndexOutOfRangeException("hashes dictionary and files collection have different count of entries!");
                                    }

                                    Index[idx].lookup = (int)(offset + headerLength);
                                    Index[idx].length = entryLength;

                                    if (hasExtra)
                                    {
                                        var curPos = br.BaseStream.Position;

                                        br.BaseStream.Seek(offset + headerLength, SeekOrigin.Begin);

                                        var extra = br.ReadBytes(8);

                                        var extra1 = (short)((extra[3] << 24) | (extra[2] << 16) | (extra[1] << 8) | extra[0]);
                                        var extra2 = (short)((extra[7] << 24) | (extra[6] << 16) | (extra[5] << 8) | extra[4]);

                                        Index[idx].lookup += 8;
#pragma warning disable CS0675 // Bitwise-or operator used on a sign-extended operand
                                        Index[idx].extra = extra1 << 16 | extra2;
#pragma warning restore CS0675 // Bitwise-or operator used on a sign-extended operand

                                        br.BaseStream.Seek(curPos, SeekOrigin.Begin);
                                    }
                                }
                            }
                        }while (br.BaseStream.Seek(nextBlock, SeekOrigin.Begin) != 0);
                    }
                }
            }
            else if ((idxPath != null) && (MulPath != null))
            {
                using (var index = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    var count = (int)(index.Length / 12);
                    IdxLength = index.Length;
                    var gc     = GCHandle.Alloc(Index, GCHandleType.Pinned);
                    var buffer = new byte[index.Length];
                    index.Read(buffer, 0, (int)index.Length);
                    Marshal.Copy(buffer, 0, gc.AddrOfPinnedObject(), (int)Math.Min(IdxLength, length * 12));
                    gc.Free();
                    for (var i = count; i < length; ++i)
                    {
                        Index[i].lookup = -1;
                        Index[i].length = -1;
                        Index[i].extra  = -1;
                    }
                }
            }
            else
            {
                Stream = null;
                return;
            }

            var patches = Verdata.Patches;

            if (file > -1)
            {
                for (var i = 0; i < patches.Length; ++i)
                {
                    var patch = patches[i];

                    if (patch.file == file && patch.index >= 0 && patch.index < length)
                    {
                        Index[patch.index].lookup = patch.lookup;
                        Index[patch.index].length = patch.length | (1 << 31);
                        Index[patch.index].extra  = patch.extra;
                    }
                }
            }
        }
예제 #5
0
        public FileIndex(string idxFile, string mulFile, int file)
        {
            string idxPath = null;

            _mulPath = null;

            if (Files.MulPath == null)
            {
                Files.LoadMulPath();
            }

            if (Files.MulPath.Count > 0)
            {
                idxPath  = Files.MulPath[idxFile.ToLower()];
                _mulPath = Files.MulPath[mulFile.ToLower()];
                if (string.IsNullOrEmpty(idxPath))
                {
                    idxPath = null;
                }
                else
                {
                    if (string.IsNullOrEmpty(Path.GetDirectoryName(idxPath)))
                    {
                        idxPath = Path.Combine(Files.RootDir, idxPath);
                    }

                    if (!File.Exists(idxPath))
                    {
                        idxPath = null;
                    }
                }

                if (string.IsNullOrEmpty(_mulPath))
                {
                    _mulPath = null;
                }
                else
                {
                    if (string.IsNullOrEmpty(Path.GetDirectoryName(_mulPath)))
                    {
                        _mulPath = Path.Combine(Files.RootDir, _mulPath);
                    }

                    if (!File.Exists(_mulPath))
                    {
                        _mulPath = null;
                    }
                }
            }

            if ((idxPath != null) && (_mulPath != null))
            {
                using (var index = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    _stream = new FileStream(_mulPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    var count = (int)(index.Length / 12);
                    IdxLength = index.Length;
                    Index     = new Entry3D[count];
                    GCHandle gc     = GCHandle.Alloc(Index, GCHandleType.Pinned);
                    var      buffer = new byte[index.Length];
                    index.Read(buffer, 0, (int)index.Length);
                    Marshal.Copy(buffer, 0, gc.AddrOfPinnedObject(), (int)index.Length);
                    gc.Free();
                }
            }
            else
            {
                _stream = null;
                Index   = new Entry3D[1];
                return;
            }

            if (file <= -1)
            {
                return;
            }

            foreach (var patch in Verdata.Patches)
            {
                if (patch.File != file || patch.Index < 0 || patch.Index >= Index.Length)
                {
                    continue;
                }

                Index[patch.Index].Lookup = patch.Lookup;
                Index[patch.Index].Length = patch.Length | (1 << 31);
                Index[patch.Index].Extra  = patch.Extra;
            }
        }
예제 #6
0
        public FileIndex(string idxFile, string mulFile, string uopFile, int length, int file, string uopEntryExtension,
                         int idxLength, bool hasExtra)
        {
            Index = new Entry3D[length];

            string idxPath = null;
            string uopPath = null;

            _mulPath = null;

            if (Files.MulPath == null)
            {
                Files.LoadMulPath();
            }

            if (Files.MulPath.Count > 0)
            {
                idxPath  = Files.MulPath[idxFile.ToLower()];
                _mulPath = Files.MulPath[mulFile.ToLower()];

                if (!string.IsNullOrEmpty(uopFile) && Files.MulPath.ContainsKey(uopFile.ToLower()))
                {
                    uopPath = Files.MulPath[uopFile.ToLower()];
                }

                if (string.IsNullOrEmpty(idxPath))
                {
                    idxPath = null;
                }
                else
                {
                    if (string.IsNullOrEmpty(Path.GetDirectoryName(idxPath)))
                    {
                        idxPath = Path.Combine(Files.RootDir, idxPath);
                    }

                    if (!File.Exists(idxPath))
                    {
                        idxPath = null;
                    }
                }

                if (string.IsNullOrEmpty(_mulPath))
                {
                    _mulPath = null;
                }
                else
                {
                    if (string.IsNullOrEmpty(Path.GetDirectoryName(_mulPath)))
                    {
                        _mulPath = Path.Combine(Files.RootDir, _mulPath);
                    }

                    if (!File.Exists(_mulPath))
                    {
                        _mulPath = null;
                    }
                }

                if (!string.IsNullOrEmpty(uopPath))
                {
                    if (string.IsNullOrEmpty(Path.GetDirectoryName(uopPath)))
                    {
                        uopPath = Path.Combine(Files.RootDir, uopPath);
                    }

                    if (File.Exists(uopPath))
                    {
                        _mulPath = uopPath;
                    }
                }
            }

            /* UOP files support code, written by Wyatt (c) www.ruosi.org
             * idxLength variable was added for compatibility with legacy code for art (see art.cs)
             * At the moment the only UOP file having entries with extra field is gumpartlegacy.uop,
             * and it's two DWORDs in the beginning of the entry.
             * It's possible that UOP can include some entries with unknown hash: not really unknown for me, but
             * not useful for reading legacy entries. That's why i removed unknown hash exception throwing from this code
             */
            if (_mulPath?.EndsWith(".uop") == true)
            {
                _stream = new FileStream(_mulPath, FileMode.Open, FileAccess.Read, FileShare.Read);

                var    fi         = new FileInfo(_mulPath);
                string uopPattern = fi.Name.Replace(fi.Extension, "").ToLowerInvariant();

                using (var br = new BinaryReader(_stream))
                {
                    br.BaseStream.Seek(0, SeekOrigin.Begin);

                    if (br.ReadInt32() != 0x50594D)
                    {
                        throw new ArgumentException("Bad UOP file.");
                    }

                    br.ReadInt64();     // version + signature
                    long nextBlock = br.ReadInt64();
                    br.ReadInt32();     // block capacity
                    _ = br.ReadInt32(); // TODO: check if we need value from here

                    if (idxLength > 0)
                    {
                        IdxLength = idxLength * 12;
                    }

                    var hashes = new Dictionary <ulong, int>();

                    for (int i = 0; i < length; i++)
                    {
                        string entryName = $"build/{uopPattern}/{i:D8}{uopEntryExtension}";
                        ulong  hash      = UopUtils.HashFileName(entryName);

                        if (!hashes.ContainsKey(hash))
                        {
                            hashes.Add(hash, i);
                        }
                    }

                    br.BaseStream.Seek(nextBlock, SeekOrigin.Begin);

                    // There are no invalid entries in .uop so we have to initialize all entries
                    // as invalid and then fill the valid ones
                    for (var i = 0; i < Index.Length; i++)
                    {
                        Index[i].Lookup = -1;
                        Index[i].Length = -1;
                        Index[i].Extra  = -1;
                    }

                    do
                    {
                        int filesCount = br.ReadInt32();
                        nextBlock = br.ReadInt64();

                        for (int i = 0; i < filesCount; i++)
                        {
                            long  offset             = br.ReadInt64();
                            int   headerLength       = br.ReadInt32();
                            int   compressedLength   = br.ReadInt32();
                            int   decompressedLength = br.ReadInt32();
                            ulong hash = br.ReadUInt64();
                            br.ReadUInt32(); // Adler32
                            short flag = br.ReadInt16();

                            int entryLength = flag == 1 ? compressedLength : decompressedLength;

                            if (offset == 0)
                            {
                                continue;
                            }

                            if (!hashes.TryGetValue(hash, out int idx))
                            {
                                continue;
                            }

                            if (idx < 0 || idx > Index.Length)
                            {
                                throw new IndexOutOfRangeException("hashes dictionary and files collection have different count of entries!");
                            }

                            Index[idx].Lookup = (int)(offset + headerLength);
                            Index[idx].Length = entryLength;

                            if (!hasExtra)
                            {
                                continue;
                            }

                            long curPos = br.BaseStream.Position;

                            br.BaseStream.Seek(offset + headerLength, SeekOrigin.Begin);

                            byte[] extra = br.ReadBytes(8);

                            var extra1 = (short)((extra[3] << 24) | (extra[2] << 16) | (extra[1] << 8) | extra[0]);
                            var extra2 = (short)((extra[7] << 24) | (extra[6] << 16) | (extra[5] << 8) | extra[4]);

                            Index[idx].Lookup += 8;
                            // changed from int b = extra1 << 16 | extra2;
                            // int cast removes compiler warning
                            Index[idx].Extra = extra1 << 16 | (int)extra2;

                            br.BaseStream.Seek(curPos, SeekOrigin.Begin);
                        }
                    }while (br.BaseStream.Seek(nextBlock, SeekOrigin.Begin) != 0);
                }
            }
            else if ((idxPath != null) && (_mulPath != null))
            {
                using (var index = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    _stream = new FileStream(_mulPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    var count = (int)(index.Length / 12);
                    IdxLength = index.Length;
                    GCHandle gc     = GCHandle.Alloc(Index, GCHandleType.Pinned);
                    var      buffer = new byte[index.Length];
                    index.Read(buffer, 0, (int)index.Length);
                    Marshal.Copy(buffer, 0, gc.AddrOfPinnedObject(), (int)Math.Min(IdxLength, length * 12));
                    gc.Free();
                    for (int i = count; i < length; ++i)
                    {
                        Index[i].Lookup = -1;
                        Index[i].Length = -1;
                        Index[i].Extra  = -1;
                    }
                }
            }
            else
            {
                _stream = null;
                return;
            }

            if (file <= -1)
            {
                return;
            }

            Entry5D[] verdataPatches = Verdata.Patches;
            foreach (var patch in verdataPatches)
            {
                if (patch.File != file || patch.Index < 0 || patch.Index >= length)
                {
                    continue;
                }

                Index[patch.Index].Lookup = patch.Lookup;
                Index[patch.Index].Length = patch.Length | (1 << 31);
                Index[patch.Index].Extra  = patch.Extra;
            }
        }