Beispiel #1
0
        protected override bool ParseSectionContent(BinaryReader binaryReader)
        {
            PriFlags = (PriDescriptorFlags)binaryReader.ReadUInt16();
            ushort includedFileListSection = binaryReader.ReadUInt16();
            binaryReader.ExpectUInt16(0);
            ushort numHierarchicalSchemaSections = binaryReader.ReadUInt16();
            ushort numDecisionInfoSections = binaryReader.ReadUInt16();
            ushort numResourceMapSections = binaryReader.ReadUInt16();
            ushort primaryResourceMapSection = binaryReader.ReadUInt16();
            if (primaryResourceMapSection != 0xFFFF)
                PrimaryResourceMapSection = new SectionRef<ResourceMapSection>(primaryResourceMapSection);
            else
                PrimaryResourceMapSection = null;
            ushort numReferencedFileSections = binaryReader.ReadUInt16();
            ushort numDataItemSections = binaryReader.ReadUInt16();
            binaryReader.ExpectUInt16(0);

            List<SectionRef<HierarchicalSchemaSection>> hierarchicalSchemaSections = new List<SectionRef<HierarchicalSchemaSection>>(numHierarchicalSchemaSections);

            for (int i = 0; i < numHierarchicalSchemaSections; i++)
                hierarchicalSchemaSections.Add(new SectionRef<HierarchicalSchemaSection>(binaryReader.ReadUInt16()));

            HierarchicalSchemaSections = hierarchicalSchemaSections;

            List<SectionRef<DecisionInfoSection>> decisionInfoSections = new List<SectionRef<DecisionInfoSection>>(numDecisionInfoSections);

            for (int i = 0; i < numDecisionInfoSections; i++)
                decisionInfoSections.Add(new SectionRef<DecisionInfoSection>(binaryReader.ReadUInt16()));

            DecisionInfoSections = decisionInfoSections;

            List<SectionRef<ResourceMapSection>> resourceMapSections = new List<SectionRef<ResourceMapSection>>(numResourceMapSections);

            for (int i = 0; i < numResourceMapSections; i++)
                resourceMapSections.Add(new SectionRef<ResourceMapSection>(binaryReader.ReadUInt16()));

            ResourceMapSections = resourceMapSections;

            List<SectionRef<ReferencedFileSection>> referencedFileSections = new List<SectionRef<ReferencedFileSection>>(numReferencedFileSections);

            for (int i = 0; i < numReferencedFileSections; i++)
                referencedFileSections.Add(new SectionRef<ReferencedFileSection>(binaryReader.ReadUInt16()));

            ReferencedFileSections = referencedFileSections;

            List<SectionRef<DataItemSection>> dataItemSections = new List<SectionRef<DataItemSection>>(numDataItemSections);

            for (int i = 0; i < numDataItemSections; i++)
                dataItemSections.Add(new SectionRef<DataItemSection>(binaryReader.ReadUInt16()));

            DataItemSections = dataItemSections;

            return true;
        }
 internal ResourceMapItemRef(SectionRef <HierarchicalSchemaSection> schemaSection, int itemIndex)
 {
     this.schemaSection = schemaSection;
     this.itemIndex     = itemIndex;
 }
Beispiel #3
0
 public T GetSectionByRef <T>(SectionRef <T> sectionRef) where T : Section
 {
     return((T)Sections[sectionRef.sectionIndex]);
 }
        protected override bool ParseSectionContent(BinaryReader binaryReader)
        {
            long sectionPosition = (binaryReader.BaseStream as SubStream)?.SubStreamPosition ?? 0;

            ushort environmentReferencesLength = binaryReader.ReadUInt16();
            ushort numEnvironmentReferences    = binaryReader.ReadUInt16();

            if (!version2)
            {
                if (environmentReferencesLength == 0 || numEnvironmentReferences == 0)
                {
                    throw new InvalidDataException();
                }
            }
            else
            {
                if (environmentReferencesLength != 0 || numEnvironmentReferences != 0)
                {
                    throw new InvalidDataException();
                }
            }
            SchemaSection = new SectionRef <HierarchicalSchemaSection>(binaryReader.ReadUInt16());
            ushort hierarchicalSchemaReferenceLength = binaryReader.ReadUInt16();

            DecisionInfoSection = new SectionRef <DecisionInfoSection>(binaryReader.ReadUInt16());
            ushort resourceValueTypeTableSize = binaryReader.ReadUInt16();
            ushort ItemToItemInfoGroupCount   = binaryReader.ReadUInt16();
            ushort itemInfoGroupCount         = binaryReader.ReadUInt16();
            uint   itemInfoCount    = binaryReader.ReadUInt32();
            uint   numCandidates    = binaryReader.ReadUInt32();
            uint   dataLength       = binaryReader.ReadUInt32();
            uint   largeTableLength = binaryReader.ReadUInt32();

            if (PriFile.GetSectionByRef(DecisionInfoSection) == null)
            {
                return(false);
            }

            byte[] environmentReferencesData = binaryReader.ReadBytes(environmentReferencesLength);

            byte[] schemaReferenceData = binaryReader.ReadBytes(hierarchicalSchemaReferenceLength);

            if (schemaReferenceData.Length != 0)
            {
                using (BinaryReader r = new BinaryReader(new MemoryStream(schemaReferenceData, false)))
                {
                    ushort majorVersion = r.ReadUInt16();
                    ushort minorVersion = r.ReadUInt16();
                    r.ExpectUInt32(0);
                    uint checksum  = r.ReadUInt32();
                    uint numScopes = r.ReadUInt32();
                    uint numItems  = r.ReadUInt32();

                    HierarchicalSchemaVersionInfo versionInfo = new HierarchicalSchemaVersionInfo(majorVersion, minorVersion, checksum, numScopes, numItems);

                    ushort stringDataLength = r.ReadUInt16();
                    r.ExpectUInt16(0);
                    uint   unknown1   = r.ReadUInt32();
                    uint   unknown2   = r.ReadUInt32();
                    string uniqueName = r.ReadNullTerminatedString(Encoding.Unicode);

                    if (uniqueName.Length != stringDataLength - 1)
                    {
                        throw new InvalidDataException();
                    }

                    HierarchicalSchemaReference = new HierarchicalSchemaReference(versionInfo, unknown1, unknown2, uniqueName);
                }
            }

            List <ResourceValueType> resourceValueTypeTable = new List <ResourceValueType>(resourceValueTypeTableSize);

            for (int i = 0; i < resourceValueTypeTableSize; i++)
            {
                binaryReader.ExpectUInt32(4);
                ResourceValueType resourceValueType = (ResourceValueType)binaryReader.ReadUInt32();
                resourceValueTypeTable.Add(resourceValueType);
            }

            List <ItemToItemInfoGroup> itemToItemInfoGroups = new List <ItemToItemInfoGroup>();

            for (int i = 0; i < ItemToItemInfoGroupCount; i++)
            {
                ushort firstItem     = binaryReader.ReadUInt16();
                ushort itemInfoGroup = binaryReader.ReadUInt16();
                itemToItemInfoGroups.Add(new ItemToItemInfoGroup(firstItem, itemInfoGroup));
            }

            List <ItemInfoGroup> itemInfoGroups = new List <ItemInfoGroup>();

            for (int i = 0; i < itemInfoGroupCount; i++)
            {
                ushort groupSize     = binaryReader.ReadUInt16();
                ushort firstItemInfo = binaryReader.ReadUInt16();
                itemInfoGroups.Add(new ItemInfoGroup(groupSize, firstItemInfo));
            }

            List <ItemInfo> itemInfos = new List <ItemInfo>();

            for (int i = 0; i < itemInfoCount; i++)
            {
                ushort decision       = binaryReader.ReadUInt16();
                ushort firstCandidate = binaryReader.ReadUInt16();
                itemInfos.Add(new ItemInfo(decision, firstCandidate));
            }

            byte[] largeTable = binaryReader.ReadBytes((int)largeTableLength);

            if (largeTable.Length != 0)
            {
                using (BinaryReader r = new BinaryReader(new MemoryStream(largeTable, false)))
                {
                    uint ItemToItemInfoGroupCountLarge = r.ReadUInt32();
                    uint itemInfoGroupCountLarge       = r.ReadUInt32();
                    uint itemInfoCountLarge            = r.ReadUInt32();

                    for (int i = 0; i < ItemToItemInfoGroupCountLarge; i++)
                    {
                        uint firstItem     = r.ReadUInt32();
                        uint itemInfoGroup = r.ReadUInt32();
                        itemToItemInfoGroups.Add(new ItemToItemInfoGroup(firstItem, itemInfoGroup));
                    }

                    for (int i = 0; i < itemInfoGroupCountLarge; i++)
                    {
                        uint groupSize     = r.ReadUInt32();
                        uint firstItemInfo = r.ReadUInt32();
                        itemInfoGroups.Add(new ItemInfoGroup(groupSize, firstItemInfo));
                    }

                    for (int i = 0; i < itemInfoCountLarge; i++)
                    {
                        uint decision       = r.ReadUInt32();
                        uint firstCandidate = r.ReadUInt32();
                        itemInfos.Add(new ItemInfo(decision, firstCandidate));
                    }

                    if (r.BaseStream.Position != r.BaseStream.Length)
                    {
                        throw new InvalidDataException();
                    }
                }
            }

            List <CandidateInfo> candidateInfos = new List <CandidateInfo>((int)numCandidates);

            for (int i = 0; i < numCandidates; i++)
            {
                byte type = binaryReader.ReadByte();

                if (type == 0x01)
                {
                    ResourceValueType resourceValueType = resourceValueTypeTable[binaryReader.ReadByte()];
                    ushort            sourceFileIndex   = binaryReader.ReadUInt16();
                    ushort            valueLocation     = binaryReader.ReadUInt16();
                    ushort            dataItemSection   = binaryReader.ReadUInt16();
                    candidateInfos.Add(new CandidateInfo(resourceValueType, sourceFileIndex, valueLocation, dataItemSection));
                }
                else if (type == 0x00)
                {
                    ResourceValueType resourceValueType = resourceValueTypeTable[binaryReader.ReadByte()];
                    ushort            length            = binaryReader.ReadUInt16();
                    uint stringOffset = binaryReader.ReadUInt32();
                    candidateInfos.Add(new CandidateInfo(resourceValueType, length, stringOffset));
                }
                else
                {
                    throw new InvalidDataException();
                }
            }

            long stringDataStartOffset = binaryReader.BaseStream.Position;

            Dictionary <ushort, CandidateSet> candidateSets = new Dictionary <ushort, CandidateSet>();

            for (int itemToItemInfoGroupIndex = 0; itemToItemInfoGroupIndex < itemToItemInfoGroups.Count; itemToItemInfoGroupIndex++)
            {
                ItemToItemInfoGroup itemToItemInfoGroup = itemToItemInfoGroups[itemToItemInfoGroupIndex];

                ItemInfoGroup itemInfoGroup;

                if (itemToItemInfoGroup.ItemInfoGroup < itemInfoGroups.Count)
                {
                    itemInfoGroup = itemInfoGroups[(int)itemToItemInfoGroup.ItemInfoGroup];
                }
                else
                {
                    itemInfoGroup = new ItemInfoGroup(1, (uint)(itemToItemInfoGroup.ItemInfoGroup - itemInfoGroups.Count));
                }

                for (uint itemInfoIndex = itemInfoGroup.FirstItemInfo; itemInfoIndex < itemInfoGroup.FirstItemInfo + itemInfoGroup.GroupSize; itemInfoIndex++)
                {
                    ItemInfo itemInfo = itemInfos[(int)itemInfoIndex];

                    ushort decisionIndex = (ushort)itemInfo.Decision;

                    Decision decision = PriFile.GetSectionByRef(DecisionInfoSection).Decisions[decisionIndex];

                    List <Candidate> candidates = new List <Candidate>(decision.QualifierSets.Count);

                    for (int i = 0; i < decision.QualifierSets.Count; i++)
                    {
                        CandidateInfo candidateInfo = candidateInfos[(int)itemInfo.FirstCandidate + i];

                        if (candidateInfo.Type == 0x01)
                        {
                            ReferencedFileRef?sourceFile;

                            if (candidateInfo.SourceFileIndex == 0)
                            {
                                sourceFile = null;
                            }
                            else
                            {
                                sourceFile = new ReferencedFileRef(candidateInfo.SourceFileIndex - 1);
                            }

                            candidates.Add(new Candidate(decision.QualifierSets[i].Index, candidateInfo.ResourceValueType, sourceFile,
                                                         new DataItemRef(new SectionRef <DataItemSection>(candidateInfo.DataItemSection), candidateInfo.DataItemIndex)));
                        }
                        else if (candidateInfo.Type == 0x00)
                        {
                            ByteSpan data = new ByteSpan(sectionPosition + stringDataStartOffset + candidateInfo.DataOffset, candidateInfo.DataLength);

                            candidates.Add(new Candidate(decision.QualifierSets[i].Index, candidateInfo.ResourceValueType, data));
                        }
                    }

                    ushort resourceMapItemIndex = (ushort)(itemToItemInfoGroup.FirstItem + (itemInfoIndex - itemInfoGroup.FirstItemInfo));

                    CandidateSet candidateSet = new CandidateSet(
                        new ResourceMapItemRef(SchemaSection, resourceMapItemIndex),
                        decisionIndex,
                        candidates);

                    candidateSets.Add(resourceMapItemIndex, candidateSet);
                }
            }

            CandidateSets = candidateSets;

            return(true);
        }
 internal DataItemRef(SectionRef <DataItemSection> dataItemSection, int itemIndex)
 {
     this.dataItemSection = dataItemSection;
     this.itemIndex       = itemIndex;
 }