예제 #1
0
        public override void Deserialize_Array(teStructuredDataMgr manager, teStructuredData data, STUField_Info field, Array target, int index)
        {
            STUInstance instanceObj = (STUInstance)DeserializeArrayInternal(manager, data, field, target);

            instanceObj.Usage = TypeUsage.InlineArray;
            target.SetValue(instanceObj, index);
        }
예제 #2
0
        public override void Deserialize(teStructuredDataMgr manager, teStructuredData data, STUField_Info field, object instance, FieldInfo target)
        {
            STUInstance instanceObj = (STUInstance)DeserializeInternal(manager, data, field, target);

            instanceObj.Usage = TypeUsage.Inline;
            target.SetValue(instance, instanceObj);
        }
예제 #3
0
        /// <summary>Read a "Version2" STU asset</summary>
        private void DeserializeV2(BinaryReader reader)
        {
            reader.BaseStream.Position = StartPos;
            HeaderChecksum             = CRC.CRC64(reader.ReadBytes(36), 36, 0xFFFFFFFFFFFFFFFF);
            reader.BaseStream.Position = StartPos;
            SerializableHelper.Deserialize(reader, out InstanceInfo);
            SerializableHelper.Deserialize(reader, out InlinedTypesInfo);
            SerializableHelper.Deserialize(reader, out FieldInfoBags);

            int dynDataSize      = reader.ReadInt32();
            int dynDataOff       = reader.ReadInt32();
            int dataBufferOffset = reader.ReadInt32();

            if (dynDataSize > 0)
            {
                reader.BaseStream.Position = dynDataOff + StartPos;
                DynData = new BinaryReader(new MemoryStream(reader.ReadBytes(dynDataSize)));
            }
            if (dataBufferOffset < reader.BaseStream.Length)
            {
                long dataSize = reader.BaseStream.Length - dataBufferOffset;
                if (dataSize > int.MaxValue)
                {
                    throw new Exception("oops");
                }

                reader.BaseStream.Position = dataBufferOffset + StartPos;
                Data = new BinaryReader(new MemoryStream(reader.ReadBytes((int)dataSize)));
            }

            if (InstanceInfo.Count > 0)
            {
                Instances = new STUInstance[InstanceInfo.Count];
                for (int i = 0; i < InstanceInfo.Count; i++)
                {
                    Instances[i] = Manager.CreateInstance(InstanceInfo[i].Hash);
                }
            }

            for (int i = 0; i != InstanceInfo.Count; ++i)
            {
                STUInstance_Info info     = InstanceInfo[i];
                STUInstance      instance = Instances[i];

                long startPosition = Data.Position();

                if (instance != null)
                {
                    instance.Deserialize(this);
                    long endPosition = Data.Position();
                }

                Data.BaseStream.Position = startPosition + info.Size;
                //if (endPosition - startPosition != info.Size)
                //    throw new Exceptions.InvalidTypeSize($"read len != type size. Type: '{instance.GetName()}', Data offset: {startPosition}");
            }
        }
예제 #4
0
        public override void Deserialize_Array(teStructuredDataMgr manager, teStructuredData data, STUField_Info field, Array target, int index)
        {
            // todo: ???
            //if (data.Format == teStructuredDataFormat.V1 && index == 0) {
            //    var n = data.Data.ReadInt64();
            //    if (n > 0) {
            //
            //    }
            //}
            STUInstance instanceObj = (STUInstance)DeserializeArrayInternal(manager, data, field, target);

            instanceObj.Usage = TypeUsage.InlineArray;
            target.SetValue(instanceObj, index);
        }
예제 #5
0
        public override void Deserialize(teStructuredDataMgr manager, teStructuredData data, STUField_Info field, object instance, FieldInfo target)
        {
            if (data.Format == teStructuredDataFormat.V1)
            {
                var n = data.Data.ReadInt64();
                if (n > 0)
                {
                }
            }

            STUInstance instanceObj = (STUInstance)DeserializeInternal(manager, data, field, target);

            instanceObj.Usage = TypeUsage.Inline;
            target.SetValue(instance, instanceObj);
        }
예제 #6
0
        public void Deserialize_Array(teStructuredDataMgr manager, teStructuredData data, STUField_Info field, Array target, int index)
        {
            if (data.Format == teStructuredDataFormat.V2)
            {
                int value = data.DynData.ReadInt32();
                data.DynData.ReadInt32(); // Padding for in-place deserialization
                if (value == -1)
                {
                    return;
                }
                if (value < data.Instances.Length)
                {
                    STUInstance embeddedInstance = data.Instances[value];
                    if (embeddedInstance != null)
                    {
                        embeddedInstance.Usage = TypeUsage.EmbedArray;
                    }

                    target.SetValue(embeddedInstance, index);
                }
                else
                {
                    throw new ArgumentOutOfRangeException(
                              $"Instance index is out of range. Id: {value}, Type: EmbeddedInstanceFieldReader, DynData offset: {data.DynData.Position() - 8}");
                }
            }
            else if (data.Format == teStructuredDataFormat.V1)
            {
                long offset = data.Data.ReadInt32(); data.Data.ReadInt32();
                if (offset == -1)
                {
                    return;
                }

                STUInstance embeddedInstance = data.GetInstanceAtOffset(offset);
                if (embeddedInstance != null)
                {
                    embeddedInstance.Usage = TypeUsage.EmbedArray;
                }

                target.SetValue(embeddedInstance, index);
            }
        }
예제 #7
0
        public void Deserialize(teStructuredDataMgr manager, teStructuredData data, STUField_Info field, object instance, FieldInfo target)
        {
            if (data.Format == teStructuredDataFormat.V2)
            {
                int value = data.Data.ReadInt32();

                if (value == -1)
                {
                    return;
                }
                if (value < data.Instances.Length)
                {
                    STUInstance embeddedInstance = data.Instances[value];
                    if (embeddedInstance != null)
                    {
                        embeddedInstance.Usage = TypeUsage.Embed;
                    }

                    target.SetValue(instance, embeddedInstance);
                }
            }
            else if (data.Format == teStructuredDataFormat.V1)
            {
                int value = data.Data.ReadInt32(); data.Data.ReadInt32();

                if (value <= 0)
                {
                    return;
                }

                STUInstance embeddedInstance = data.GetInstanceAtOffset(value);
                if (embeddedInstance != null)
                {
                    embeddedInstance.Usage = TypeUsage.Embed;
                }

                target.SetValue(instance, embeddedInstance);
            }
        }
예제 #8
0
        /// <summary>Read a "Version1" STU asset</summary>
        private void DeserializeV1(BinaryReader reader)
        {
            _instanceOffsets = new Dictionary <long, STUInstance>();

            reader.BaseStream.Position = StartPos;

            STUHeaderV1 header = reader.Read <STUHeaderV1>();

            InstanceInfoV1 = new STUInstanceRecordV1[header.InstanceCount];
            Instances      = new STUInstance[header.InstanceCount];
            for (int i = 0; i < header.InstanceCount; i++)
            {
                STUInstanceRecordV1 record = reader.Read <STUInstanceRecordV1>();
                InstanceInfoV1[i] = record;

                long position = reader.BaseStream.Position;
                reader.BaseStream.Position = record.Offset + StartPos;
                uint instanceHash = reader.ReadUInt32();
                uint nextOffset   = reader.ReadUInt32();

                STUInstance instance = Manager.CreateInstance(instanceHash);
                _instanceOffsets[record.Offset] = instance;
                Instances[i] = instance;

                reader.BaseStream.Position = position;
            }

            Data = reader; // hmm

            for (int i = 0; i < header.InstanceCount; i++)
            {
                STUInstanceRecordV1 record = InstanceInfoV1[i];

                if (Instances[i] == null)
                {
                    continue;
                }

                // dump instance

                /*reader.BaseStream.Position = record.Offset + StartPos;
                 * Directory.CreateDirectory("STUV1Dump");
                 * using (Stream dumpFile = File.OpenWrite($"STUV1Dump\\{Instances[i].GetType().Name}_{i}")) {
                 *  dumpFile.SetLength(0);
                 *  int next;
                 *  {
                 *      IEnumerable<STUInstanceRecordV1> more = InstanceInfoV1.Where(x => x.Offset > record.Offset);
                 *      if (more.Any()) {
                 *          next = InstanceInfoV1.Where(x => x.Offset > record.Offset).Min(x => x.Offset);
                 *      } else {
                 *          next = (int)Data.BaseStream.Length; // err, not great
                 *      }
                 *  }
                 *  reader.BaseStream.Position = record.Offset + StartPos;
                 *  int size = next - (int) reader.BaseStream.Position;
                 *  byte[] buf = reader.ReadBytes(size);
                 *  dumpFile.Write(buf, 0, size);
                 * }*/

                const uint instPrefixSize = sizeof(uint) * 2; // nameCrc and "nextOffset"

                reader.BaseStream.Position = record.Offset + StartPos + instPrefixSize;

                //uint instanceHash = reader.ReadUInt32();
                //uint nextOffset = reader.ReadUInt32();

                //if (instanceHash == 0xEA30C5E9) continue;
                //if (instanceHash == 0x05C7059E) {
                //    Debugger.Break();
                //}
            #if RELEASE
                try {
            #endif
                var instance = Instances[i];
                instance.m_posInDataAtDeserializeCall = instPrefixSize;
                instance.Deserialize(this);
            #if RELEASE
            }
            catch (Exception) {
                // ignored
            }
            #endif

                //if (instanceHash == 0x05C7059E) {
                //    Debugger.Break();
                //}
            }

            Instances[0].Usage = TypeUsage.Root;
        }
예제 #9
0
        public void Deserialize(teStructuredData assetFile, STUField_Info field)
        {
            BinaryReader data    = assetFile.Data;
            BinaryReader dynData = assetFile.DynData;

            int offset = data.ReadInt32();

            if (offset == -1)
            {
                return;
            }
            dynData.Seek(offset);
            int unk2Size = dynData.ReadInt32();

            if (unk2Size == 0)
            {
                return;
            }
            Unknown1 = dynData.ReadUInt32();
            long unk2Offset = dynData.ReadInt64();
            long dataOffset = dynData.ReadInt64();

            dynData.Seek(unk2Offset);
            Unknown2 = new uint[unk2Size];
            for (int i = 0; i != unk2Size; ++i)
            {
                Unknown2[i] = dynData.ReadUInt32();
            }

            dynData.Seek(dataOffset);
            uint mapSize = Unknown2.Last();

            for (int i = 0; i != mapSize; ++i)
            {
                ulong key = dynData.ReadUInt64();
                // Last 4 bytes are padding for in-place deserialization.
                int value = (int)dynData.ReadUInt64();
                if (value == -1)
                {
                    Add(key, null);
                }
                else
                {
                    if (value < assetFile.Instances.Length)
                    {
                        STUInstance stuType = assetFile.Instances[value];
                        if (stuType != null)
                        {
                            stuType.Usage = TypeUsage.HashMap;
                        }

                        if (stuType is T casted)
                        {
                            Add(key, casted);
                        }
                        else
                        {
                            throw new InvalidCastException(
                                      $"Attempted to cast '{stuType?.GetType().Name}' to '{typeof(T).Name}'");
                        }
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(
                                  $"DataRoot index is out of range. Id: {value}, Type: STUHashMap<{typeof(T).Name}>, Data offset: {dynData.Position() - 8}");
                    }
                }
            }
        }