//===================================================== // Calculate map hash(reversed) and dump map signature(if any) // - return the starting pos of signature block(-1 if none) //===================================================== public static long MapGetSignatureInfo(string mappath, ref byte[] maphash, ref byte[] mapsignature) { long signature_pos = -1; string mapname = Path.GetFileName(mappath); byte[] mapnamebytes = Encoding.ASCII.GetBytes(mapname.ToUpper()); //upper filename System.Security.Cryptography.SHA1 sha1 = System.Security.Cryptography.SHA1.Create(); Stream input = File.OpenRead(mappath); byte[] buffer_old = new byte[200]; byte[] buffer = new byte[200]; //read 200 bytes each time int bytesRead, bytesRead_old; bool findblockheader = false; //Mpq is a vaild map bytesRead = input.Read(buffer, 0, buffer.Length); //read mpq header if (buffer[0] == Convert.ToByte('H') && buffer[1] == Convert.ToByte('M') && buffer[2] == Convert.ToByte('3') && buffer[3] == Convert.ToByte('W')) { //sha1.TransformBlock(buffer, 0, buffer.Length, null, 0); Array.Copy(buffer, buffer_old, buffer.Length); bytesRead_old = bytesRead; } else { throw new Exception("Not a vaild map."); } while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) { //Construct a new temporiary bytes of 2 trunks, in case the header sign is splited. byte[] temp = new byte[buffer_old.Length + buffer.Length]; Array.Copy(buffer_old, 0, temp, 0, buffer_old.Length); Array.Copy(buffer, 0, temp, buffer_old.Length, buffer.Length); //search for the block header 'NGIS' int index; if ((index = IndexOfBytes(temp, SIGNATURE_HEADER)) != -1) { //if found! Console.WriteLine("Found Signature."); sha1.TransformBlock(temp, 0, index, null, 0); findblockheader = true; //dump signature input.Position = input.Position - temp.Length + index + SIGNATURE_HEADER.Length; //set the stream pos after 'NGIS' signature_pos = input.Position - SIGNATURE_HEADER.Length; //get the signature block starting pos mapsignature = new byte[input.Length - input.Position]; input.Read(mapsignature, 0, mapsignature.Length); Array.Reverse(mapsignature); break; } else { sha1.TransformBlock(buffer_old, 0, bytesRead_old, null, 0); Array.Copy(buffer, buffer_old, buffer.Length); bytesRead_old = bytesRead; } } if (!findblockheader) { sha1.TransformBlock(buffer_old, 0, bytesRead_old, null, 0); } sha1.TransformBlock(mapnamebytes, 0, mapnamebytes.Length, null, 0); //Add upper file name to the end sha1.TransformFinalBlock(buffer, 0, 0); //Calculate Hash: Console.WriteLine("SHA1:"); maphash = new byte[sha1.Hash.Length]; sha1.Hash.CopyTo(maphash, 0); input.Close(); input.Dispose(); Array.Reverse(maphash); Console.WriteLine(BitConverter.ToString(maphash)); return(signature_pos); }