/// <summary> /// Cosntructs a new instance of UltimaPackage. /// </summary> /// <param name="filePath">Path to the .uop file.</param> public UltimaPackage(string filePath) { _FilePath = filePath; _Files = new Dictionary <ulong, UltimaPackageFile>(); _Stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); _Reader = new BinaryReader(_Stream); byte[] id = _Reader.ReadBytes(4); if (id[0] != 'M' || id[1] != 'Y' || id[2] != 'P' || id[3] != 0) { throw new FormatException("Not a Mythic Package file!"); } _Version = _Reader.ReadInt32(); _Reader.ReadInt32(); // Constant number long nextBlockAddress = _Reader.ReadInt64(); long blockSize = _Reader.ReadInt32(); // Unknown _Reader.ReadInt32(); // Move to first block header do { _Stream.Seek(nextBlockAddress, SeekOrigin.Begin); int fileCount = _Reader.ReadInt32(); nextBlockAddress = _Reader.ReadInt64(); for (int i = 0; i < blockSize; i++) { if (i < fileCount) { // Actual file UltimaPackageFile file = new UltimaPackageFile(this, _Reader); if (file.FileAddress == 0) { continue; } if (!_Files.ContainsKey(file.FileNameHash)) { _Files.Add(file.FileNameHash, file); } } else { // Blank _Stream.Seek(UltimaPackageFile.FileHeaderSize, SeekOrigin.Current); } } }while (nextBlockAddress > 0); }
/// <summary> /// Cosntructs a new instance of UltimaPackage. /// </summary> /// <param name="filePath">Path to the .uop file.</param> public UltimaPackage( string filePath ) { _FilePath = filePath; _Files = new Dictionary<ulong, UltimaPackageFile>(); _Stream = File.Open( filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ); _Reader = new BinaryReader( _Stream ); byte[] id = _Reader.ReadBytes( 4 ); if ( id[ 0 ] != 'M' || id[ 1 ] != 'Y' || id[ 2 ] != 'P' || id[ 3 ] != 0 ) throw new FormatException( "Not a Mythic Package file!" ); _Version = _Reader.ReadInt32(); _Reader.ReadInt32(); // Constant number long nextBlockAddress = _Reader.ReadInt64(); long blockSize = _Reader.ReadInt32(); // Unknown _Reader.ReadInt32(); // Move to first block header do { _Stream.Seek( nextBlockAddress, SeekOrigin.Begin ); int fileCount = _Reader.ReadInt32(); nextBlockAddress = _Reader.ReadInt64(); for ( int i = 0; i < blockSize; i++ ) { if ( i < fileCount ) { // Actual file UltimaPackageFile file = new UltimaPackageFile( this, _Reader ); if ( file.FileAddress == 0 ) continue; if ( !_Files.ContainsKey( file.FileNameHash ) ) _Files.Add( file.FileNameHash, file ); } else { // Blank _Stream.Seek( UltimaPackageFile.FileHeaderSize, SeekOrigin.Current ); } } } while ( nextBlockAddress > 0 ); }
/// <summary> /// Gets file data. /// </summary> /// <param name="fileNameHash">File hash.</param> /// <returns>File data.</returns> public byte[] GetFile(ulong fileNameHash) { UltimaPackageFile file = null; if (!_Files.TryGetValue(fileNameHash, out file)) { return(null); } _Stream.Seek(file.FileAddress, SeekOrigin.Begin); byte[] compressed = new byte[file.CompressedSize]; if (_Reader.Read(compressed, 0, file.CompressedSize) != file.CompressedSize) { throw new FileLoadException("Error reading file"); } if (file.Compression == FileCompression.Zlib) { int decompressedSize = file.DecompressedSize; byte[] decompressed = new byte[decompressedSize]; ZLibError error; if (SystemInfo.IsX64) { error = Zlib64.Decompress(decompressed, ref decompressedSize, compressed, compressed.Length); } else { error = Zlib32.Decompress(decompressed, ref decompressedSize, compressed, compressed.Length); } if (decompressedSize != file.DecompressedSize) { throw new PackageException("Error decompressing vile. Decompressed length missmatch. Defined={0} Actual={1}", file.DecompressedSize, decompressedSize); } if (error == ZLibError.Okay) { return(decompressed); } throw new PackageException("Error decompressing file. Error={0}", error); } return(compressed); }