public void Write <TItem>(TItem obj, BinaryWriter writer, HashWriter hashWriter) where TItem : BiffData { var tag = Encoding.Default.GetBytes(Name); if (Name.Length < 4) { tag = tag.Concat(new byte[4 - Name.Length]).ToArray(); } writer.Write(Data.Length + 4); writer.Write(tag); writer.Write(Data); hashWriter?.Write(tag); hashWriter?.Write(Data); }
public override void Write <TItem>(TItem obj, BinaryWriter writer, HashWriter hashWriter) { if (!(GetValue(obj) is Material[] materials)) { return; } using (var stream = new MemoryStream()) using (var dataWriter = new BinaryWriter(stream)) { foreach (var material in materials) { if (IsPhysics) { material.PhysicsMaterialData.Write(dataWriter); } else { material.UpdateData(); material.MaterialData.Write(dataWriter); } } var data = stream.ToArray(); WriteStart(writer, data.Length, hashWriter); writer.Write(data); hashWriter?.Write(data); } }
public override void Write <TItem>(TItem obj, BinaryWriter writer, HashWriter hashWriter) { if (obj is PrimitiveData primitiveData) { if (!primitiveData.Use3DMesh) { // don't write animation if not using 3d mesh return; } for (var i = 0; i < primitiveData.Mesh.AnimationFrames.Count; i++) { var animationData = SerializeAnimation(primitiveData.Mesh.AnimationFrames[i]); var data = IsCompressed ? BiffZlib.Compress(animationData) : animationData; WriteStart(writer, 4, hashWriter, "M3AY"); writer.Write(data.Length); WriteStart(writer, data.Length, hashWriter); writer.Write(data); hashWriter?.Write(data); } } else { throw new InvalidOperationException("Unknown type for [" + GetType().Name + "] on field \"" + Name + "\"."); } }
protected static void WriteEnd(BinaryWriter writer, HashWriter hashWriter) { var endTag = Encoding.Default.GetBytes("ENDB"); writer.Write(4); writer.Write(endTag); hashWriter?.Write(endTag); }
public void SerializeTransaction(Transaction transaction, HashWriter s) { bool fAllowWitness = (s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS) == 0; s.Write(transaction.Version); s.Write(transaction.TransactionsIn); s.Write(transaction.TransactionsOut); if (flags & 1 != 0) { for (size_t i = 0; i < tx.vin.size(); i++) { s << tx.vin[i].scriptWitness.stack; } } s << tx.nLockTime; }
protected void WriteStart(BinaryWriter writer, int dataLength, HashWriter hashWriter) { var tag = Encoding.Default.GetBytes(Name); if (Name.Length < 4) { tag = tag.Concat(new byte[4 - Name.Length]).ToArray(); } writer.Write(dataLength + 4); writer.Write(tag); hashWriter?.Write(tag); // only write tag }
public override void Write <TItem>(TItem obj, BinaryWriter writer, HashWriter hashWriter) { if (Type == typeof(byte[])) { var bytes = GetValue(obj) as byte[]; WriteStart(writer, bytes.Length, WriteHash(obj) ? hashWriter : null); writer.Write(bytes); if (WriteHash(obj)) { hashWriter?.Write(bytes); } } }
public ISliceHash ComputeSliceHash(ISliceId sliceId, DateTime t) { // We do not consider the methods in the same type at the moment SliceDefinition sliceDef; // If we do not know the slice, we just return null if (!this.slices.TryGetValue(sliceId, out sliceDef)) { return(null); } // TODO: wire the hashing option using (var tw = new HashWriter(false)) { foreach (var methodId in sliceDef.Dependencies) { tw.Write(methodId); tw.Write(':'); var methodHash = this.GetHashForDate(methodId, t, false); Method methodModel; if (methodHash == null || !this.TryGetMethodModelForHash(methodHash, out methodModel)) { tw.WriteLine("<null>"); } else { tw.WriteLine(this.GetResultHash(methodModel)); } } return(new SliceHash(tw.GetHash())); } }
public override void Write <TItem>(TItem obj, BinaryWriter writer, HashWriter hashWriter) { if (obj is PrimitiveData primitiveData) { if (!primitiveData.Use3DMesh) { return; } var indexData = SerializeIndices(primitiveData); var data = IsCompressed ? BiffZlib.Compress(indexData) : indexData; WriteStart(writer, data.Length, hashWriter); writer.Write(data); hashWriter?.Write(data); } else { throw new InvalidOperationException("Unknown type for [" + GetType().Name + "] on field \"" + Name + "\"."); } }
protected void WriteValue <TItem, TField>(TItem obj, BinaryWriter writer, Action <BinaryWriter, TField> write, HashWriter hashWriter, Func <int, int> overrideLength = null) where TItem : BiffData { var value = GetValue(obj); // don't write null values if (value == null) { return; } using (var stream = new MemoryStream()) using (var dataWriter = new BinaryWriter(stream)) { if (Type == typeof(TField)) { write(dataWriter, (TField)value); } else if (Type == typeof(TField[])) { var arr = value as TField[]; if (Index >= 0) { write(dataWriter, arr[Index]); } else { foreach (var val in arr) { if (TagAll) { using (var separateStream = new MemoryStream()) using (var separateDataWriter = new BinaryWriter(separateStream)) { write(separateDataWriter, val); var separateData = separateStream.ToArray(); var separateLength = overrideLength?.Invoke(separateData.Length) ?? separateData.Length; WriteStart(writer, separateLength, hashWriter); writer.Write(separateData); if (WriteHash(obj)) { hashWriter?.Write(separateData); } } } else { write(dataWriter, val); } } } } else { throw new InvalidOperationException("Unknown type for [" + GetType().Name + "] on field \"" + Name + "\"."); } if (TagAll) { // everything's been written already return; } var data = stream.ToArray(); var length = overrideLength?.Invoke(data.Length) ?? data.Length; WriteStart(writer, length, WriteHash(obj) ? hashWriter : null); writer.Write(data); if (WriteHash(obj)) { hashWriter?.Write(LengthAfterTag ? data.Skip(4).ToArray() : data); } } }
public string GenerateHash() { if (!string.IsNullOrWhiteSpace(Hash)) { return(Hash); } using var output = new HashWriter(false); output.Write(IsOutgoing); if (!HGame.IsValidIdentifier(Class.QName.Name, true)) { output.Write(Class.Instance, true); output.Write(Class.Instance.Constructor); output.Write(References.Count); foreach (HReference reference in References) { output.Write(reference.IsStatic); output.Write(reference.IsAnonymous); output.Write(reference.MethodRank); output.Write(reference.InstructionRank); output.Write(reference.FromMethod); output.Write(reference.FromClass.Constructor); output.Write(reference.FromClass.Instance.Constructor); } if (!IsOutgoing && Parser != null) { output.Write(Parser.Instance, true); } } else { output.Write(Class.QName.Name); } return(Hash = output.GenerateHash()); }
private void Compare(string[] args) { using (var game_1 = new HGame(args[0])) using (var game_2 = new HGame(args[1])) { game_1.Disassemble(); game_2.Disassemble(); var matchedHashes = new List <string>(); var oldUnmatched = new Dictionary <string, List <ASMethod> >(); var unmatchedMethods = new Dictionary <string, List <ASMethod> >(); foreach (ASMethod method in game_1.ABCFiles[0].Methods) { using (var hasher = new HashWriter(false)) { hasher.Write(method); string hash = hasher.GenerateMD5Hash(); List <ASMethod> methods = null; if (!unmatchedMethods.TryGetValue(hash, out methods)) { methods = new List <ASMethod>(); unmatchedMethods.Add(hash, methods); } methods.Add(method); } } foreach (ASMethod method in game_2.ABCFiles[0].Methods) { using (var hasher = new HashWriter(false)) { hasher.Write(method); string hash = hasher.GenerateMD5Hash(); if (unmatchedMethods.ContainsKey(hash)) { matchedHashes.Add(hash); unmatchedMethods.Remove(hash); } else if (!matchedHashes.Contains(hash)) { List <ASMethod> methods = null; if (!oldUnmatched.TryGetValue(hash, out methods)) { methods = new List <ASMethod>(); oldUnmatched.Add(hash, methods); } methods.Add(method); } } } var changes = string.Empty; foreach (string hash in unmatchedMethods.Keys) { changes += $"[{hash}]\r\n{{\r\n"; foreach (ASMethod method in unmatchedMethods[hash]) { changes += $" {(method.Container?.QName.Name ?? "Anonymous")}\r\n"; changes += $" {method.ToAS3()}\r\n\r\n"; } changes += $"}}\r\n"; } } }