Esempio n. 1
0
        public void GameSettingStringHandler(
            IMutagenReadStream stream,
            MajorRecordHeader major,
            BinaryFileProcessor.ConfigConstructor instr,
            List <KeyValuePair <uint, uint> > processedStrings,
            IStringsLookup overlay,
            ref uint newIndex)
        {
            stream.Position -= major.HeaderLength;
            var majorRec = stream.GetMajorRecordFrame();

            if (!majorRec.TryLocateSubrecordFrame("EDID", out var edidRec))
            {
                throw new ArgumentException();
            }
            if (edidRec.Content[0] != (byte)'s')
            {
                return;
            }
            if (!majorRec.TryLocateSubrecordPinFrame("DATA", out var dataRec))
            {
                throw new ArgumentException();
            }
            stream.Position += dataRec.Location;
            AStringsAlignment.ProcessStringLink(stream, instr, processedStrings, overlay, ref newIndex);
        }
Esempio n. 2
0
        public void FillMajorRecords(
            OverlayStream stream,
            int finalPos,
            int offset,
            RecordTypeConverter?recordTypeConverter,
            RecordTypeFillWrapper fill)
        {
            int?lastParsed = null;
            Dictionary <RecordType, int>?recordParseCount = null;

            while (!stream.Complete && stream.Position < finalPos)
            {
                MajorRecordHeader majorMeta = stream.GetMajorRecord();
                var minimumFinalPos         = stream.Position + majorMeta.TotalLength;
                var parsed = fill(
                    stream: stream,
                    finalPos: finalPos,
                    offset: offset,
                    recordParseCount: recordParseCount,
                    type: majorMeta.RecordType,
                    lastParsed: lastParsed,
                    recordTypeConverter: recordTypeConverter);
                if (!parsed.KeepParsing)
                {
                    break;
                }
                if (parsed.DuplicateParseMarker != null)
                {
                    if (recordParseCount == null)
                    {
                        recordParseCount = new Dictionary <RecordType, int>();
                    }
                    recordParseCount[parsed.DuplicateParseMarker !.Value] = recordParseCount.GetOrAdd(parsed.DuplicateParseMarker !.Value) + 1;
Esempio n. 3
0
        public static void Sort(
            Func <IMutagenReadStream> streamCreator,
            Stream outputStream,
            GameRelease release)
        {
            using var inputStream   = streamCreator();
            using var locatorStream = streamCreator();
            using var writer        = new MutagenWriter(outputStream, release, dispose: false);
            while (!inputStream.Complete)
            {
                long noRecordLength;
                foreach (var grupLoc in RecordLocator.IterateBaseGroupLocations(locatorStream))
                {
                    noRecordLength = grupLoc.Value - inputStream.Position;
                    inputStream.WriteTo(writer.BaseStream, (int)noRecordLength);

                    // If complete overall, return
                    if (inputStream.Complete)
                    {
                        return;
                    }

                    var groupMeta = inputStream.GetGroup();

                    var storage = new Dictionary <FormKey, List <ReadOnlyMemorySlice <byte> > >();
                    using (var grupFrame = new MutagenFrame(inputStream).SpawnWithLength(groupMeta.TotalLength))
                    {
                        inputStream.WriteTo(writer.BaseStream, inputStream.MetaData.Constants.GroupConstants.HeaderLength);
                        locatorStream.Position = grupLoc.Value;
                        foreach (var rec in RecordLocator.ParseTopLevelGRUP(locatorStream))
                        {
                            MajorRecordHeader majorMeta = inputStream.GetMajorRecord();
                            storage.GetOrAdd(rec.FormKey).Add(inputStream.ReadMemory(checked ((int)majorMeta.TotalLength), readSafe: true));
                            if (grupFrame.Complete)
                            {
                                continue;
                            }
                            if (inputStream.TryGetGroup(out var subGroupMeta))
                            {
                                storage.GetOrAdd(rec.FormKey).Add(inputStream.ReadMemory(checked ((int)subGroupMeta.TotalLength), readSafe: true));
                            }
                        }
                    }

                    // Sorts via Record ID (as opposed to just the first 6 bytes)
                    foreach (var item in storage.OrderBy((i) => i.Key.ID))
                    {
                        foreach (var bytes in item.Value)
                        {
                            writer.Write(bytes);
                        }
                    }
                }

                inputStream.WriteTo(writer.BaseStream, (int)inputStream.Remaining);
            }
        }
Esempio n. 4
0
            public static GroupMajorRecordCacheWrapper <T> Factory(
                IBinaryReadStream stream,
                ReadOnlyMemorySlice <byte> data,
                BinaryOverlayFactoryPackage package,
                int offset)
            {
                Dictionary <FormKey, int> locationDict = new Dictionary <FormKey, int>();

                stream.Position -= package.MetaData.Constants.GroupConstants.HeaderLength;
                var groupMeta = stream.GetGroup(package.MetaData);
                var finalPos  = stream.Position + groupMeta.TotalLength;

                stream.Position += package.MetaData.Constants.GroupConstants.HeaderLength;
                // Parse MajorRecord locations
                ObjectType?lastParsed = default;

                while (stream.Position < finalPos)
                {
                    VariableHeader varMeta = package.MetaData.Constants.NextRecordVariableMeta(stream.RemainingMemory);
                    if (varMeta.IsGroup)
                    {
                        if (lastParsed != ObjectType.Record)
                        {
                            throw new DataMisalignedException("Unexpected Group encountered which was not after a major record: " + GroupRecordTypeGetter <T> .GRUP_RECORD_TYPE);
                        }
                        stream.Position += checked ((int)varMeta.TotalLength);
                        lastParsed       = ObjectType.Group;
                    }
                    else
                    {
                        MajorRecordHeader majorMeta = package.MetaData.Constants.MajorRecord(stream.RemainingMemory);
                        if (majorMeta.RecordType != GroupRecordTypeGetter <T> .GRUP_RECORD_TYPE)
                        {
                            throw new DataMisalignedException("Unexpected type encountered when parsing MajorRecord locations: " + majorMeta.RecordType);
                        }
                        var formKey = FormKey.Factory(package.MetaData.MasterReferences !, majorMeta.FormID.Raw);
                        locationDict.Add(formKey, checked ((int)(stream.Position - offset)));
                        stream.Position += checked ((int)majorMeta.TotalLength);
                        lastParsed       = ObjectType.Record;
                    }
                }

                return(new GroupMajorRecordCacheWrapper <T>(
                           locationDict,
                           data,
                           package));
            }
Esempio n. 5
0
        public void PerkStringHandler(
            IMutagenReadStream stream,
            MajorRecordHeader major,
            BinaryFileProcessor.ConfigConstructor instr,
            List <KeyValuePair <uint, uint> > processedStrings,
            IStringsLookup overlay,
            ref uint newIndex)
        {
            var  majorCompletePos = stream.Position + major.ContentLength;
            long?lastepft         = null;

            while (stream.Position < majorCompletePos)
            {
                var sub = stream.GetSubrecord();
                switch (sub.RecordTypeInt)
                {
                case RecordTypeInts.FULL:
                case RecordTypeInts.EPF2:
                    AStringsAlignment.ProcessStringLink(stream, instr, processedStrings, overlay, ref newIndex);
                    break;

                case RecordTypeInts.EPFT:
                    lastepft = stream.Position;
                    break;

                case RecordTypeInts.EPFD:
                    var pos = stream.Position;
                    stream.Position = lastepft.Value;
                    var epftFrame = stream.ReadSubrecordFrame();
                    if (epftFrame.Content[0] == (byte)APerkEntryPointEffect.ParameterType.LString)
                    {
                        stream.Position = pos;
                        AStringsAlignment.ProcessStringLink(stream, instr, processedStrings, overlay, ref newIndex);
                    }
                    stream.Position = pos;
                    break;

                default:
                    break;
                }
                stream.Position += sub.TotalLength;
            }
        }
Esempio n. 6
0
        private void Align(
            IMutagenReadStream stream,
            MajorRecordHeader major,
            BinaryFileProcessor.ConfigConstructor instr,
            List <KeyValuePair <uint, uint> > processedStrings,
            IStringsLookup overlay,
            ref uint newIndex)
        {
            var majorCompletePos = stream.Position + major.ContentLength;

            while (stream.Position < majorCompletePos)
            {
                var sub = stream.GetSubrecord();
                if (StringTypes.Contains(sub.RecordType))
                {
                    ProcessStringLink(stream, instr, processedStrings, overlay, ref newIndex);
                }
                stream.Position += sub.TotalLength;
            }
        }
Esempio n. 7
0
        private static void AlignWorldChildren(
            IMutagenReadStream reader,
            MutagenWriter writer)
        {
            reader.WriteTo(writer.BaseStream, 4);
            ReadOnlyMemorySlice <byte>?roadStorage = null;
            ReadOnlyMemorySlice <byte>?cellStorage = null;
            var grupBytes = new List <ReadOnlyMemorySlice <byte> >();

            for (int i = 0; i < 3; i++)
            {
                MajorRecordHeader majorMeta = reader.GetMajorRecord();
                switch (majorMeta.RecordType.Type)
                {
                case "ROAD":
                    roadStorage = reader.ReadMemory(checked ((int)majorMeta.TotalLength));
                    break;

                case "CELL":
                    if (cellStorage != null)
                    {
                        throw new ArgumentException();
                    }
                    var startPos = reader.Position;
                    var cellMeta = reader.GetMajorRecord();
                    reader.Position += cellMeta.TotalLength;
                    var  cellGroupMeta = reader.GetGroup();
                    long cellGrupLen;
                    if (cellGroupMeta.IsGroup &&
                        cellGroupMeta.GroupType == (int)GroupTypeEnum.CellChildren)
                    {
                        cellGrupLen = cellGroupMeta.TotalLength;
                    }
                    else
                    {
                        cellGrupLen = 0;
                    }
                    reader.Position = startPos;
                    cellStorage     = reader.ReadMemory(checked ((int)(cellMeta.TotalLength + cellGrupLen)));
                    break;

                case "GRUP":
                    if (roadStorage != null &&
                        cellStorage != null)
                    {
                        i = 3;     // end loop
                        continue;
                    }
                    var groupMeta = reader.GetGroup();
                    grupBytes.Add(reader.ReadMemory(checked ((int)groupMeta.TotalLength)));
                    break;

                case "WRLD":
                    i = 3;     // end loop
                    continue;

                default:
                    throw new NotImplementedException();
                }
            }
            if (roadStorage != null)
            {
                writer.Write(roadStorage.Value);
            }
            if (cellStorage != null)
            {
                writer.Write(cellStorage.Value);
            }
            foreach (var item in grupBytes)
            {
                writer.Write(item);
            }
        }
Esempio n. 8
0
        public static void Sort(
            Func <Stream> streamCreator,
            Stream outputStream,
            GameMode gameMode)
        {
            var meta = new ParsingBundle(GameConstants.Get(gameMode));

            using var inputStream   = new MutagenBinaryReadStream(streamCreator(), meta);
            using var locatorStream = new MutagenBinaryReadStream(streamCreator(), meta);
            using var writer        = new MutagenWriter(outputStream, gameMode, dispose: false);
            while (!inputStream.Complete)
            {
                long noRecordLength;
                foreach (var grupLoc in RecordLocator.IterateBaseGroupLocations(locatorStream))
                {
                    noRecordLength = grupLoc.Value - inputStream.Position;
                    inputStream.WriteTo(writer.BaseStream, (int)noRecordLength);

                    // If complete overall, return
                    if (inputStream.Complete)
                    {
                        return;
                    }

                    var groupMeta = inputStream.GetGroup();
                    if (!groupMeta.IsGroup)
                    {
                        throw new ArgumentException();
                    }

                    var storage = new Dictionary <FormID, List <ReadOnlyMemorySlice <byte> > >();
                    using (var grupFrame = new MutagenFrame(inputStream).SpawnWithLength(groupMeta.TotalLength))
                    {
                        inputStream.WriteTo(writer.BaseStream, meta.Constants.GroupConstants.HeaderLength);
                        locatorStream.Position = grupLoc.Value;
                        foreach (var rec in RecordLocator.ParseTopLevelGRUP(locatorStream))
                        {
                            MajorRecordHeader majorMeta = inputStream.GetMajorRecord();
                            storage.TryCreateValue(rec.FormID).Add(inputStream.ReadMemory(checked ((int)majorMeta.TotalLength), readSafe: true));
                            if (grupFrame.Complete)
                            {
                                continue;
                            }
                            GroupHeader subGroupMeta = inputStream.GetGroup();
                            if (subGroupMeta.IsGroup)
                            {
                                storage.TryCreateValue(rec.FormID).Add(inputStream.ReadMemory(checked ((int)subGroupMeta.TotalLength), readSafe: true));
                            }
                        }
                    }

                    foreach (var item in storage.OrderBy((i) => i.Key.ID))
                    {
                        foreach (var bytes in item.Value)
                        {
                            writer.Write(bytes);
                        }
                    }
                }

                inputStream.WriteTo(writer.BaseStream, (int)inputStream.Remaining);
            }
        }