Example #1
0
        /// <summary>
        ///     Reads Sounds and def
        /// </summary>
        public void Initialize(Verdata verdata)
        {
            m_Cache     = new UOSound[0xFFF];
            m_Removed   = new bool[0xFFF];
            m_FileIndex = new FileIndex("soundidx.mul", "sound.mul", "soundLegacyMUL.uop", 0xFFF, 8, ".dat", -1, false, verdata, _Files);
            var reg = new Regex(@"(\d{1,3}) \x7B(\d{1,3})\x7D (\d{1,3})", RegexOptions.Compiled);

            m_Translations = new Dictionary <int, int>();

            string line;
            string path = _Files.GetFilePath("Sound.def");

            if (path == null)
            {
                return;
            }
            using (var reader = new StreamReader(path))
            {
                while ((line = reader.ReadLine()) != null)
                {
                    if (((line = line.Trim()).Length != 0) && !line.StartsWith("#"))
                    {
                        Match match = reg.Match(line);

                        if (match.Success)
                        {
                            m_Translations.Add(int.Parse(match.Groups[1].Value), int.Parse(match.Groups[2].Value));
                        }
                    }
                }
            }
        }
Example #2
0
 /// <summary>
 /// Inizializza una nuova istanza della classe <see cref="T:System.Object"/>.
 /// </summary>
 public Light(Verdata verdata, Files files)
 {
     _files      = files;
     m_FileIndex = new FileIndex("lightidx.mul", "light.mul", 100, -1, verdata, files);
     m_Cache     = new Bitmap[100];
     m_Removed   = new bool[100];
 }
Example #3
0
 /// <summary>
 /// Inizializza una nuova istanza della classe <see cref="T:System.Object"/>.
 /// </summary>
 public AnimationEdit(Verdata verdata, Animations animations, Files files)
 {
     this._Animations = animations;
     _files           = files;
     m_FileIndex      = new FileIndex("Anim.idx", "Anim.mul", 6, verdata, _files);
     m_FileIndex2     = new FileIndex("Anim2.idx", "Anim2.mul", -1, verdata, _files);
     m_FileIndex3     = new FileIndex("Anim3.idx", "Anim3.mul", -1, verdata, _files);
     m_FileIndex4     = new FileIndex("Anim4.idx", "Anim4.mul", -1, verdata, _files);
     m_FileIndex5     = new FileIndex("Anim5.idx", "Anim5.mul", -1, verdata, _files);
     if (m_FileIndex.IdxLength > 0)
     {
         animcache = new AnimIdx[m_FileIndex.IdxLength / 12];
     }
     if (m_FileIndex2.IdxLength > 0)
     {
         animcache = new AnimIdx[m_FileIndex2.IdxLength / 12];
     }
     if (m_FileIndex3.IdxLength > 0)
     {
         animcache = new AnimIdx[m_FileIndex3.IdxLength / 12];
     }
     if (m_FileIndex4.IdxLength > 0)
     {
         animcache = new AnimIdx[m_FileIndex4.IdxLength / 12];
     }
     if (m_FileIndex5.IdxLength > 0)
     {
         animcache = new AnimIdx[m_FileIndex5.IdxLength / 12];
     }
 }
Example #4
0
 public void Init()
 {
     Verdata       = new Verdata(this);
     RadarCol      = new RadarCol(this);
     Hues          = new Hues(this);
     Gumps         = new Gumps(this);
     Art           = new Art(this);
     TileData      = new TileData(this);
     Skills        = new Skills(this);
     Light         = new Light(this);
     Sound         = new Sounds(this);
     Textures      = new Textures(this);
     Multis        = new Multis(this);
     AnimationEdit = new AnimationEdit(this);
     ASCIIText     = new ASCIIText(this);
     Maps          = new Dictionary <MapNames, Map>
     {
         { MapNames.Felucca, Map.Felucca(this) },
         { MapNames.Ilshenar, Map.Ilshenar(this) },
         { MapNames.Malas, Map.Malas(this) },
         { MapNames.Trammel, Map.Trammel(this) },
         { MapNames.Tokuno, Map.Tokuno(this) },
         { MapNames.TerMur, Map.TerMur(this) }
     };
     MultiMap   = new Ultima.MultiMap(this);
     Animations = new Animations(this);
 }
Example #5
0
        public Gumps(Verdata verdata, Files files)
		{
		    _Files = files;
		    if (m_FileIndex != null)
			{
				m_Cache = new Bitmap[m_FileIndex.Index.Length];
				m_Removed = new bool[m_FileIndex.Index.Length];
			}
			else
			{
				m_Cache = new Bitmap[0xFFFF];
				m_Removed = new bool[0xFFFF];
			}

            try
            {
                m_FileIndex = new FileIndex("Gumpidx.mul", "Gumpart.mul", "gumpartLegacyMUL.uop", 12, -1, ".tga", -1, true, verdata, _Files);
                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();
        }
Example #6
0
        public Stream Seek(int index, out int length, out int extra, out bool patched)
        {
            if (index < 0 || index >= Index.Length)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            Entry3D e = Index[index];

            if (e.Lookup < 0)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            length = e.Length & 0x7FFFFFFF;
            extra  = e.Extra;

            if ((e.Length & (1 << 31)) != 0)
            {
                patched = true;
                Verdata.Seek(e.Lookup);
                return(Verdata.Stream);
            }

            if (e.Length < 0)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            if ((_stream?.CanRead != true) || (!_stream.CanSeek))
            {
                _stream = _mulPath == null ? null : new FileStream(_mulPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            }

            if (_stream == null)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            if (_stream.Length < e.Lookup)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            patched = false;

            _stream.Seek(e.Lookup, SeekOrigin.Begin);
            return(_stream);
        }
Example #7
0
 public Textures(Verdata verdata, Files files)
 {
     this._Files = files;
     m_FileIndex = new FileIndex("Texidx.mul", "Texmaps.mul", 0x4000, 10, verdata, _Files);
     m_Cache     = new Bitmap[0x4000];
     m_Removed   = new bool[0x4000];
     m_patched.Clear();
 }
Example #8
0
        /// <summary>
        /// Inizializza una nuova istanza della classe <see cref="T:System.Object"/>.
        /// </summary>
        public Art(Verdata verdata, Files files)
        {
            _Files      = files;
            m_Cache     = new Bitmap[0xFFFF];
            m_Removed   = new bool[0xFFFF];
            m_FileIndex = new FileIndex("Artidx.mul", "Art.mul", "artLegacyMUL.uop", 0x10000 /*0x13FDC*/, 4, ".tga",
                                        0x13FDC, false, verdata, files);

            m_patched.Clear();
            Modified = false;
        }
Example #9
0
        /// <summary>
        /// Inizializza una nuova istanza della classe <see cref="T:System.Object"/>.
        /// </summary>
        public Animations(Verdata verdata, Hues hues, Files files)
        {
            _files       = files;
            m_FileIndex  = new FileIndex("Anim.idx", "Anim.mul", 0x40000, 6, verdata, _files);
            m_FileIndex2 = new FileIndex("Anim2.idx", "Anim2.mul", 0x10000, -1, verdata, files);
            m_FileIndex3 = new FileIndex("Anim3.idx", "Anim3.mul", 0x20000, -1, verdata, files);
            m_FileIndex4 = new FileIndex("Anim4.idx", "Anim4.mul", 0x20000, -1, verdata, files);
            m_FileIndex5 = new FileIndex("Anim5.idx", "Anim5.mul", 0x20000, -1, verdata, files);

            _BodyConverter = new BodyConverter(_files);
            BodyTable      = new BodyTable(_files);
            _hues          = hues;
            LoadTable();
        }
Example #10
0
 /// <summary>
 /// Inizializza una nuova istanza della classe <see cref="T:System.Object"/>.
 /// </summary>
 ///
 public Skills(Verdata verdata, Files files)
 {
     _files         = files;
     m_FileIndex    = new FileIndex("skills.idx", "skills.mul", 16, verdata, _files);
     m_SkillEntries = new List <SkillInfo>();
     for (int i = 0; i < m_FileIndex.Index.Length; ++i)
     {
         SkillInfo info = GetSkill(i);
         if (info == null)
         {
             break;
         }
         m_SkillEntries.Add(info);
     }
 }
Example #11
0
        public Stream Seek(int index, out int length, out int extra, out bool patched)
        {
            if (index < 0 || index >= Index.Length)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            Entry3D e = Index[index];

            if (e.lookup < 0)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            length = e.length & 0x7FFFFFFF;
            extra  = e.extra;

            if ((e.length & (1 << 31)) != 0)
            {
                patched = true;
                Verdata.Seek(e.lookup);
                return(Verdata.Stream);
            }

            if (e.length < 0)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            if ((Stream == null) || (!Stream.CanRead) || (!Stream.CanSeek))
            {
                if (MulPath == null)
                {
                    Stream = null;
                }
                else
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                }
            }

            if (Stream == null)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }
            else if (Stream.Length < e.lookup)
            {
                length  = extra = 0;
                patched = false;
                return(null);
            }

            patched = false;

            Stream.Seek(e.lookup, SeekOrigin.Begin);
            return(Stream);
        }
Example #12
0
 public Sounds(Verdata verdata, Files files)
 {
     _Files = files;
     Initialize(verdata);
 }
Example #13
0
        public FileIndex(string idxFile, string mulFile, int file, Verdata verdata, Files files)
        {
            _files        = files;
            this._Verdata = verdata;
            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.ReadWrite, FileShare.ReadWrite))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                    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;
            }
            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;
                    }
                }
            }
        }
Example #14
0
        public FileIndex(
            string idxFile,
            string mulFile,
            string uopFile,
            int length,
            int file,
            string uopEntryExtension,
            int idxLength,
            bool hasExtra, Verdata verdata, Files files)
        {
            _files        = files;
            this._Verdata = verdata;
            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.ReadWrite, FileShare.ReadWrite))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);

                    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
                        int count = br.ReadInt32();

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

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

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

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

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

                        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;
                                }

                                int idx;
                                if (hashes.TryGetValue(hash, out 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)
                                    {
                                        long curPos = br.BaseStream.Position;

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

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

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

                                        Index[idx].lookup += 8;
                                        Index[idx].extra   = extra1 << 16 | 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.ReadWrite, FileShare.ReadWrite))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                    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;
            }

            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 < length)
                    {
                        Index[patch.index].lookup = patch.lookup;
                        Index[patch.index].length = patch.length | (1 << 31);
                        Index[patch.index].extra  = patch.extra;
                    }
                }
            }
        }
Example #15
0
 public FileIndex(string idxFile, string mulFile, int length, int file, Verdata verdata, Files files)
     : this(idxFile, mulFile, null, length, file, ".dat", -1, false, verdata, files)
 {
 }