예제 #1
0
 private void OnInvalidFile(MPKFile file)
 {
     if (InvalidFile != null)
     {
         InvalidFile(file, new EventArgs());
     }
 }
예제 #2
0
        /// <summary>
        /// Adds a file to the MPK
        /// </summary>
        /// <param name="file">The file to add</param>
        /// <returns>true if successfull, false if the file is already contained</returns>
        public bool AddFile(MPKFile file)
        {
            if (!_files.ContainsKey(file.Header.Name))
            {
                _files.Add(file.Header.Name, file);
                return(true);
            }

            return(false);
        }
예제 #3
0
        /// <summary>
        /// Reads a MPK from a binary reader
        /// </summary>
        /// <param name="rdr">The binary reader pointing to the MPK</param>
        private void ReadArchive(BinaryReader rdr)
        {
            _files.Clear();

            _crc.Value = 0;
            _sizeDir   = 0;
            _sizeName  = 0;
            _numFiles  = 0;

            var buf = new byte[16];

            rdr.Read(buf, 0, 16);

            for (byte i = 0; i < 16; ++i)
            {
                buf[i] ^= i;
            }

            _crc.Value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
            _sizeDir   = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
            _sizeName  = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
            _numFiles  = (buf[12] << 24) | (buf[13] << 16) | (buf[14] << 8) | buf[15];

            buf = new byte[_sizeName];
            rdr.Read(buf, 0, _sizeName);

            var inf = new Inflater();

            inf.SetInput(buf);
            buf = new byte[1024];
            inf.Inflate(buf);
            buf[inf.TotalOut] = 0;

            _name = Marshal.ConvertToString(buf);

            long totalin = 0;

            buf = ReadDirectory(rdr, ref totalin);

            using (var directory = new MemoryStream(buf))
            {
                long pos = rdr.BaseStream.Position;
                long len = rdr.BaseStream.Seek(0, SeekOrigin.End);
                rdr.BaseStream.Position = pos;

                buf = new byte[len - pos];
                rdr.Read(buf, 0, buf.Length);

                using (var files = new MemoryStream(buf))
                {
                    rdr.BaseStream.Position = pos - totalin;
                    buf = new byte[totalin];
                    rdr.Read(buf, 0, buf.Length);

                    var crc = new Crc32();
                    crc.Reset();
                    crc.Update(buf);

                    if (crc.Value != _crc.Value)
                    {
                        throw new Exception("Invalid or corrupt MPK");
                    }

                    while (directory.Position < directory.Length && files.Position < files.Length)
                    {
                        crc.Reset();

                        buf = new byte[MPKFileHeader.MaxSize];
                        directory.Read(buf, 0, MPKFileHeader.MaxSize);

                        MPKFileHeader hdr;

                        using (var hdrStream = new MemoryStream(buf))
                        {
                            using (var hdrRdr = new BinaryReader(hdrStream, Encoding.UTF8))
                            {
                                hdr = new MPKFileHeader(hdrRdr);
                            }
                        }

                        var compbuf = new byte[hdr.CompressedSize];
                        files.Read(compbuf, 0, compbuf.Length);

                        crc.Update(compbuf, 0, compbuf.Length);

                        inf.Reset();
                        inf.SetInput(compbuf, 0, compbuf.Length);
                        buf = new byte[hdr.UncompressedSize];
                        inf.Inflate(buf, 0, buf.Length);

                        var file = new MPKFile(compbuf, buf, hdr);

                        if (crc.Value != hdr.CRC.Value)
                        {
                            OnInvalidFile(file);
                            continue;
                        }

                        _files.Add(hdr.Name.ToLower(), file);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Writes the MPK to a specific filename
        /// </summary>
        /// <param name="fname"></param>
        public void Write(string fname)
        {
            Deflater def;

            byte[] buf, dir, name;
            var    files = new MPKFile[_files.Count];

            using (var dirmem = new MemoryStream(_files.Count * MPKFileHeader.MaxSize))
            {
                int  index     = 0;
                uint offset    = 0;
                uint diroffset = 0;

                foreach (MPKFile file in _files.Values)
                {
                    file.Header.DirectoryOffset = diroffset;
                    file.Header.Offset          = offset;
                    files[index] = file;

                    using (var wrtr = new BinaryWriter(dirmem, Encoding.UTF8))
                    {
                        file.Header.Write(wrtr);
                    }

                    offset    += file.Header.UncompressedSize;
                    diroffset += file.Header.CompressedSize;
                    index++;
                }

                def = new Deflater();
                def.SetInput(dirmem.GetBuffer(), 0, (int)dirmem.Position);
                def.Finish();

                dir = new byte[dirmem.Position];
                def.Deflate(dir);
                _sizeDir = (int)def.TotalOut;
            }

            def = new Deflater();

            _crc.Reset();
            _crc.Update(dir, 0, _sizeDir);

            def.SetInput(Encoding.UTF8.GetBytes(_name));
            def.Finish();

            name = new byte[_name.Length];
            def.Deflate(name);

            _numFiles = _files.Count;
            _sizeName = (int)def.TotalOut;

            using (var filemem = new MemoryStream())
            {
                using (var wrtr = new BinaryWriter(filemem, Encoding.UTF8))
                {
                    wrtr.Write((int)_crc.Value);
                    wrtr.Write(_sizeDir);
                    wrtr.Write(_sizeName);
                    wrtr.Write(_numFiles);

                    buf = new byte[16];
                    Buffer.BlockCopy(filemem.GetBuffer(), 0, buf, 0, 16);

                    for (byte i = 0; i < 16; i++)
                    {
                        buf[i] ^= i;
                    }
                }
            }

            using (FileStream fileStream = File.Open(fname, FileMode.Create, FileAccess.Write))
            {
                using (var wrtr = new BinaryWriter(fileStream, Encoding.UTF8))
                {
                    wrtr.Write(Magic);
                    wrtr.Write((byte)2);
                    wrtr.Write(buf, 0, 16);
                    wrtr.Write(name, 0, _sizeName);
                    wrtr.Write(dir, 0, _sizeDir);

                    foreach (MPKFile file in files)
                    {
                        wrtr.Write(file.CompressedData);
                    }
                }
            }
        }
예제 #5
0
 /// <summary>
 /// Removes a file from the MPK
 /// </summary>
 /// <param name="file">The file to remove</param>
 /// <returns>true if the file was successfully removed, false if it wasn't in the MPK</returns>
 public bool RemoveFile(MPKFile file)
 {
     return(RemoveFile(file.Header.Name));
 }
예제 #6
0
파일: MPK.cs 프로젝트: mynew4/DOLSharp
		private void OnInvalidFile(MPKFile file)
		{
			if (InvalidFile != null)
			{
				InvalidFile(file, new EventArgs());
			}
		}
예제 #7
0
파일: MPK.cs 프로젝트: mynew4/DOLSharp
		/// <summary>
		/// Reads a MPK from a binary reader
		/// </summary>
		/// <param name="rdr">The binary reader pointing to the MPK</param>
		private void ReadArchive(BinaryReader rdr)
		{
			_files.Clear();

			_crc.Value = 0;
			_sizeDir = 0;
			_sizeName = 0;
			_numFiles = 0;

			var buf = new byte[16];
			rdr.Read(buf, 0, 16);

			for (byte i = 0; i < 16; ++i)
			{
				buf[i] ^= i;
			}

			_crc.Value = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]);
			_sizeDir = ((buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]);
			_sizeName = ((buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11]);
			_numFiles = ((buf[12] << 24) | (buf[13] << 16) | (buf[14] << 8) | buf[15]);

			buf = new byte[_sizeName];
			rdr.Read(buf, 0, _sizeName);

			var inf = new Inflater();
			inf.SetInput(buf);
			buf = new byte[1024];
			inf.Inflate(buf);
			buf[inf.TotalOut] = 0;

			_name = Marshal.ConvertToString(buf);

			long totalin = 0;
			buf = ReadDirectory(rdr, ref totalin);

			using (var directory = new MemoryStream(buf))
			{
				long pos = rdr.BaseStream.Position;
				long len = rdr.BaseStream.Seek(0, SeekOrigin.End);
				rdr.BaseStream.Position = pos;

				buf = new byte[len - pos];
				rdr.Read(buf, 0, buf.Length);

				using (var files = new MemoryStream(buf))
				{
					rdr.BaseStream.Position = pos - totalin;
					buf = new byte[totalin];
					rdr.Read(buf, 0, buf.Length);

					var crc = new Crc32();
					crc.Reset();
					crc.Update(buf);

					if (crc.Value != _crc.Value)
					{
						throw new Exception("Invalid or corrupt MPK");
					}

					while (directory.Position < directory.Length && files.Position < files.Length)
					{
						crc.Reset();

						buf = new byte[MPKFileHeader.MaxSize];
						directory.Read(buf, 0, MPKFileHeader.MaxSize);

						MPKFileHeader hdr;

						using (var hdrStream = new MemoryStream(buf))
						{
							using (var hdrRdr = new BinaryReader(hdrStream, Encoding.UTF8))
							{
								hdr = new MPKFileHeader(hdrRdr);
							}
						}

						var compbuf = new byte[hdr.CompressedSize];
						files.Read(compbuf, 0, compbuf.Length);

						crc.Update(compbuf, 0, compbuf.Length);

						inf.Reset();
						inf.SetInput(compbuf, 0, compbuf.Length);
						buf = new byte[hdr.UncompressedSize];
						inf.Inflate(buf, 0, buf.Length);

						var file = new MPKFile(compbuf, buf, hdr);

						if (crc.Value != hdr.CRC.Value)
						{
							OnInvalidFile(file);
							continue;
						}

						_files.Add(hdr.Name.ToLower(), file);
					}
				}
			}
		}
예제 #8
0
파일: MPK.cs 프로젝트: mynew4/DOLSharp
		/// <summary>
		/// Writes the MPK to a specific filename
		/// </summary>
		/// <param name="fname"></param>
		public void Write(string fname)
		{
			Deflater def;
			byte[] buf, dir, name;
			var files = new MPKFile[_files.Count];

			using (var dirmem = new MemoryStream(_files.Count*MPKFileHeader.MaxSize))
			{
				int index = 0;
				uint offset = 0;
				uint diroffset = 0;

				foreach (MPKFile file in _files.Values)
				{
					file.Header.DirectoryOffset = diroffset;
					file.Header.Offset = offset;
					files[index] = file;

					using (var wrtr = new BinaryWriter(dirmem, Encoding.UTF8))
					{
						file.Header.Write(wrtr);
					}

					offset += file.Header.UncompressedSize;
					diroffset += file.Header.CompressedSize;
					index++;
				}

				def = new Deflater();
				def.SetInput(dirmem.GetBuffer(), 0, (int) dirmem.Position);
				def.Finish();

				dir = new byte[dirmem.Position];
				def.Deflate(dir);
				_sizeDir = (int) def.TotalOut;
			}

			def = new Deflater();

			_crc.Reset();
			_crc.Update(dir, 0, _sizeDir);

			def.SetInput(Encoding.UTF8.GetBytes(_name));
			def.Finish();

			name = new byte[_name.Length];
			def.Deflate(name);

			_numFiles = _files.Count;
			_sizeName = (int) def.TotalOut;

			using (var filemem = new MemoryStream())
			{
				using (var wrtr = new BinaryWriter(filemem, Encoding.UTF8))
				{
					wrtr.Write((int) _crc.Value);
					wrtr.Write(_sizeDir);
					wrtr.Write(_sizeName);
					wrtr.Write(_numFiles);

					buf = new byte[16];
					Buffer.BlockCopy(filemem.GetBuffer(), 0, buf, 0, 16);

					for (byte i = 0; i < 16; i++)
					{
						buf[i] ^= i;
					}
				}
			}

			using (FileStream fileStream = File.Open(fname, FileMode.Create, FileAccess.Write))
			{
				using (var wrtr = new BinaryWriter(fileStream, Encoding.UTF8))
				{
					wrtr.Write(Magic);
					wrtr.Write((byte) 2);
					wrtr.Write(buf, 0, 16);
					wrtr.Write(name, 0, _sizeName);
					wrtr.Write(dir, 0, _sizeDir);

					foreach (MPKFile file in files)
					{
						wrtr.Write(file.CompressedData);
					}
				}
			}
		}
예제 #9
0
파일: MPK.cs 프로젝트: mynew4/DOLSharp
		/// <summary>
		/// Removes a file from the MPK
		/// </summary>
		/// <param name="file">The file to remove</param>
		/// <returns>true if the file was successfully removed, false if it wasn't in the MPK</returns>
		public bool RemoveFile(MPKFile file)
		{
			return RemoveFile(file.Header.Name);
		}
예제 #10
0
파일: MPK.cs 프로젝트: mynew4/DOLSharp
		/// <summary>
		/// Adds a file to the MPK
		/// </summary>
		/// <param name="file">The file to add</param>
		/// <returns>true if successfull, false if the file is already contained</returns>
		public bool AddFile(MPKFile file)
		{
			if (!_files.ContainsKey(file.Header.Name))
			{
				_files.Add(file.Header.Name, file);
				return true;
			}

			return false;
		}