public static ISTU NewInstance(Stream stream, uint owVersion, Type type = null) { if (stream == null) { return(null); } long pos = stream.Position; using (BinaryReader reader = new BinaryReader(stream, Encoding.Default, true)) { if (type != null) { return((ISTU)Activator.CreateInstance(type, stream, owVersion)); // return new Impl.Version2HashComparer.Version2Comparer(stream, owVersion); // for debug // return new Impl.Version2HashComparer.MapComparer(stream, owVersion); // for debug } if (Version1.IsValidVersion(reader)) { stream.Position = pos; return(new Version1(stream, owVersion)); } if (Version2.IsValidVersion(reader)) { stream.Position = pos; return(new Version2(stream, owVersion)); } throw new InvalidDataException("Data stream is not a STU file"); } }
protected override void ReadInstanceData(long offset) { if (_InstanceTypes == null) { LoadInstanceTypes(); } Stream.Position = offset; GetHeaderCRC(); Stream.Position = offset; ChainedInstances = new Dictionary <uint, List <ChainedInstanceInfo> >(); using (BinaryReader reader = new BinaryReader(Stream, Encoding.UTF8, true)) { if (Version1.IsValidVersion(reader)) { Version1Comparer ver1 = new Version1Comparer(Stream, BuildVersion); InstanceData = ver1.InstanceData; InternalInstances = ver1.InternalInstances; return; } Stream.Position = offset; if (!ReadHeaderData(reader)) { return; } long stuOffset = Header.Offset; for (int chainedI = 0; chainedI < InstanceInfo.Length; ++chainedI) { if (InstanceInfo[chainedI].AssignInstanceIndex <= -1 || InstanceInfo[chainedI].AssignInstanceIndex >= InstanceInfo.Length) { continue; } if (!ChainedInstances.ContainsKey(InstanceInfo[chainedI].InstanceChecksum)) { ChainedInstances[InstanceInfo[chainedI].InstanceChecksum] = new List <ChainedInstanceInfo>(); } ChainedInstances[InstanceInfo[chainedI].InstanceChecksum].Add(new ChainedInstanceInfo { Checksum = InstanceInfo[chainedI].InstanceChecksum, OwnerChecksum = InstanceInfo[InstanceInfo[chainedI].AssignInstanceIndex].InstanceChecksum, OwnerField = InstanceInfo[chainedI].AssignFieldChecksum }); } InstanceGuessData = new InstanceGuessData[InstanceInfo.Length]; InstanceData = new InstanceData[InstanceInfo.Length]; for (int i = 0; i < InstanceInfo.Length; ++i) { Stream.Position = stuOffset; stuOffset += InstanceInfo[i].InstanceSize; int fieldListIndex = reader.ReadInt32(); if (fieldListIndex < 0) { Debugger.Log(0, "STU", $"[Version2HashComparer:{InstanceInfo[i].InstanceChecksum:X}]: Instance field list was not valid ({fieldListIndex})\n"); continue; } if (InstanceJSON == null) { FieldGuessData[] fields = GuessInstance(InstanceFields[fieldListIndex], reader, (int)InstanceInfo[i].InstanceSize - 4, InstanceInfo[i].InstanceChecksum); InstanceGuessData[i] = new InstanceGuessData { Fields = fields, IsChained = ChainedInstances.ContainsKey(InstanceInfo[i].InstanceChecksum), Checksum = InstanceInfo[i].InstanceChecksum, Size = InstanceInfo[i].InstanceSize, ChainInfo = ChainedInstances.ContainsKey(InstanceInfo[i].InstanceChecksum) ? ChainedInstances[InstanceInfo[i].InstanceChecksum].ToArray() : null }; } else { InstanceData[i] = GetInstanceData(InstanceInfo[i].InstanceChecksum, reader, InstanceInfo[i].InstanceSize, fieldListIndex); } } } }