예제 #1
0
 public void Overflow()
 {
     Assert.Throws <OverflowException>(() =>
     {
         byte[] b         = new byte[ushort.MaxValue + 100];
         byte[] b2        = new byte[ushort.MaxValue + 1];
         using var writer = new MutagenWriter(new MemoryStream(b), GameConstants.Oblivion);
         using var header = HeaderExport.Header(writer, RecordTypes.EDID, ObjectType.Subrecord);
         writer.Write(b2);
     });
 }
예제 #2
0
        private void ProcessLeveledItemDataFields(
            MajorRecordFrame majorFrame,
            long fileOffset)
        {
            if (!majorFrame.TryLocateSubrecordFrame(RecordTypes.DATA, out var dataFrame, out var dataIndex))
            {
                return;
            }

            int amount   = 0;
            var dataFlag = dataFrame.AsUInt8();

            if (dataFlag == 1)
            {
                var lvld = majorFrame.LocateSubrecord(RecordTypes.LVLD, out var index);
                index += lvld.HeaderLength + 1;
                this._Instructions.SetAddition(
                    loc: index + fileOffset,
                    addition: new byte[]
                {
                    (byte)'L',
                    (byte)'V',
                    (byte)'L',
                    (byte)'F',
                    0x1,
                    0x0,
                    0x2
                });
                amount += 7;
            }
            else
            {
                var    existingLen = dataFrame.ContentLength;
                byte[] lenData     = new byte[2];
                using (var writer = new MutagenWriter(new MemoryStream(lenData), this.GameRelease))
                {
                    writer.Write((ushort)(existingLen - 7));
                }
                this._Instructions.SetSubstitution(
                    loc: fileOffset + Plugins.Internals.Constants.HeaderLength,
                    sub: lenData);
            }

            // Remove DATA
            var dataRange = new RangeInt64(dataIndex + fileOffset, dataIndex + fileOffset + 7 - 1);

            this._Instructions.SetRemove(dataRange);
            amount -= (int)dataRange.Width;

            ProcessLengths(
                majorFrame,
                amount,
                fileOffset);
        }
예제 #3
0
 static partial void WriteBinaryAnimationCountCustom(MutagenWriter writer, IIdleMarkerGetter item)
 {
     if (!item.Animations.TryGet(out var anims))
     {
         return;
     }
     using (HeaderExport.Subrecord(writer, RecordTypes.IDLC))
     {
         writer.Write(checked ((byte)anims.Count));
     }
 }
예제 #4
0
            public static partial void WriteBinaryParentLogicCustom(MutagenWriter writer, IANavigationMeshDataGetter item)
            {
                switch (item)
                {
                case ICellNavigationMeshDataGetter cell:
                    FormKeyBinaryTranslation.Instance.Write(writer, cell.UnusedWorldspaceParent.FormKey);
                    FormKeyBinaryTranslation.Instance.Write(writer, cell.Parent.FormKey);
                    break;

                case IWorldspaceNavigationMeshDataGetter worldspace:
                    FormKeyBinaryTranslation.Instance.Write(writer, worldspace.Parent.FormKey);
                    var coords = worldspace.Coordinates;
                    writer.Write(coords.X);
                    writer.Write(coords.Y);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
예제 #5
0
            public static void WriteObject(MutagenWriter writer, IScriptObjectPropertyGetter obj, ushort objFormat)
            {
                switch (objFormat)
                {
                case 2:
                    writer.Write(obj.Unused);
                    writer.Write(obj.Alias);
                    writer.Write(writer.MetaData.MasterReferences !.GetFormID(obj.Object.FormKey).Raw);
                    break;

                case 1:
                    writer.Write(writer.MetaData.MasterReferences !.GetFormID(obj.Object.FormKey).Raw);
                    writer.Write(obj.Alias);
                    writer.Write(obj.Unused);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
예제 #6
0
 static partial void WriteBinaryDataCustom(MutagenWriter writer, IGameSettingBoolGetter item)
 {
     if (!item.Data.TryGet(out var data))
     {
         return;
     }
     using (HeaderExport.Subrecord(writer, RecordTypes.DATA))
     {
         writer.Write(data ? 1 : 0);
     }
 }
예제 #7
0
 public void Dispose()
 {
     _tributary.Position = 0;
     if (_tributary.Length <= ushort.MaxValue)
     {
         using (HeaderExport.Subrecord(_writer, _mainRecord))
         {
             _tributary.CopyTo(_writer.BaseStream);
         }
     }
     else
     {
         using (HeaderExport.Subrecord(_writer, _overflowRecord))
         {
             _writer.Write(checked ((uint)_tributary.Length));
         }
         _writer.Write(_mainRecord.TypeInt);
         _writer.WriteZeros(2);
         _tributary.CopyTo(_writer.BaseStream);
     }
 }
예제 #8
0
 public static partial void WriteBinaryAliasIndexCustom(MutagenWriter writer, IFindMatchingRefNearAliasGetter item)
 {
     if (item.AliasIndex is not {
     } index)
     {
         return;
     }
     using (HeaderExport.Subrecord(writer, RecordTypes.ALNA))
     {
         writer.Write((int)index);
     }
 }
예제 #9
0
 public void WriteNullable(
     MutagenWriter writer,
     ITranslatedStringGetter?item,
     StringBinaryType binaryType,
     StringsSource source)
 {
     if (item == null)
     {
         return;
     }
     if (writer.MetaData.StringsWriter == null)
     {
         writer.Write(
             item.String ?? string.Empty,
             binaryType: binaryType);
     }
     else
     {
         writer.Write(writer.MetaData.StringsWriter.Register(item, source));
     }
 }
예제 #10
0
        private static void AlignCellChildren(
            BinaryReadStream mutaReader,
            MutagenWriter writer)
        {
            writer.Write(mutaReader.ReadSpan(4, readSafe: false));
            var storage = new Dictionary <GroupTypeEnum, ReadOnlyMemorySlice <byte> >();

            for (int i = 0; i < 3; i++)
            {
                mutaReader.Position += 4;
                var subLen = mutaReader.ReadInt32();
                mutaReader.Position += 4;
                var subGrupType = (GroupTypeEnum)mutaReader.ReadUInt32();
                mutaReader.Position -= 16;
                switch (subGrupType)
                {
                case GroupTypeEnum.CellPersistentChildren:
                case GroupTypeEnum.CellTemporaryChildren:
                case GroupTypeEnum.CellVisibleDistantChildren:
                    break;

                default:
                    i = 3;     // end loop
                    continue;
                }
                storage[subGrupType] = mutaReader.ReadMemory(subLen, readSafe: true);
            }
            if (storage.TryGetValue(GroupTypeEnum.CellPersistentChildren, out var content))
            {
                writer.Write(content);
            }
            if (storage.TryGetValue(GroupTypeEnum.CellTemporaryChildren, out content))
            {
                writer.Write(content);
            }
            if (storage.TryGetValue(GroupTypeEnum.CellVisibleDistantChildren, out content))
            {
                writer.Write(content);
            }
        }
예제 #11
0
        private static byte[] CreateIlStrings(IReadOnlyList <string> strs, IMutagenEncoding encoding)
        {
            var ret    = new byte[100];
            var writer = new MutagenWriter(
                new BinaryWriter(new MemoryStream(ret)),
                GameConstants.SkyrimSE);

            writer.Write((uint)strs.Count);
            writer.Write((uint)strs.Sum(s => s.Length + 5));
            var sum = 0;

            // Write index
            for (int i = 0; i < strs.Count; i++)
            {
                writer.Write(i + 1);
                writer.Write(sum);
                sum += strs[i].Length + 5;
            }

            // Write strings
            for (int i = 0; i < Strs.Count; i++)
            {
                writer.Write(strs[i].Length + 1);
                writer.Write(strs[i], StringBinaryType.NullTerminate, encoding);
            }

            return(ret);
        }
예제 #12
0
        public void ParseRecordLocationsByCount_Single_EndOfStream()
        {
            MemoryTributary data = new MemoryTributary();

            using (MutagenWriter writer = new MutagenWriter(data, GameConstants.Oblivion))
            {
                using (HeaderExport.Subrecord(writer, RecordTypes.EDID))
                {
                    writer.Write(0);
                }
                using (HeaderExport.Subrecord(writer, RecordTypes.EDID))
                {
                    writer.Write(1);
                }
                using (HeaderExport.Subrecord(writer, RecordTypes.EDID))
                {
                    writer.Write(2);
                }
            }

            data.Position = 0;
            var triggers = new HashSet <RecordType>()
            {
                RecordTypes.EDID
            };
            var stream = new OverlayStream(data.ToArray(), new ParsingBundle(GameConstants.Oblivion, masterReferences: null !));
            var pos    = BinaryOverlay.ParseRecordLocationsByCount(
                stream,
                3,
                triggers.ToGetter(),
                GameConstants.Oblivion.SubConstants,
                skipHeader: false);

            Assert.Equal(3, pos.Length);
            Assert.Equal(0, pos[0]);
            Assert.Equal(10, pos[1]);
            Assert.Equal(20, pos[2]);
            Assert.Equal(30, stream.Position);
            Assert.True(stream.Complete);
        }
예제 #13
0
            public static void Write(MutagenWriter writer, IEnumerable <IATopicReferenceGetter> topics)
            {
                foreach (var item in topics)
                {
                    using var header = HeaderExport.Subrecord(writer, RecordTypes.PDTO);
                    switch (item)
                    {
                    case ITopicReferenceGetter refGetter:
                        writer.Write((int)ATopicReference.TopicType.Ref);
                        FormLinkBinaryTranslation.Instance.Write(writer, refGetter.Reference);
                        break;

                    case ITopicReferenceSubtypeGetter subType:
                        writer.Write((int)ATopicReference.TopicType.Subtype);
                        writer.Write(subType.Subtype.TypeInt);
                        break;

                    default:
                        break;
                    }
                }
            }
예제 #14
0
            public static partial void WriteBinaryZoomCustom(MutagenWriter writer, ICameraPathGetter item)
            {
                byte e = (byte)item.Zoom;

                if (!item.ZoomMustHaveCameraShots)
                {
                    e += 128;
                }
                using (HeaderExport.Subrecord(writer, RecordTypes.DATA))
                {
                    writer.Write(e);
                }
            }
예제 #15
0
 public void WriteNullable(
     MutagenWriter writer,
     string?item,
     StringBinaryType binaryType = StringBinaryType.NullTerminate)
 {
     if (item == null)
     {
         return;
     }
     writer.Write(
         item,
         binaryType: binaryType);
 }
예제 #16
0
            static partial void WriteBinaryParameterParsingCustom(MutagenWriter writer, IFunctionConditionDataGetter item)
            {
                var paramTypes = ConditionData.GetParameterTypes(item.Function);

                switch (paramTypes.First.GetCategory())
                {
                case ConditionData.ParameterCategory.None:
                case ConditionData.ParameterCategory.Number:
                    writer.Write(item.ParameterOneNumber);
                    break;

                case ConditionData.ParameterCategory.Form:
                    FormKeyBinaryTranslation.Instance.Write(writer, item.ParameterOneRecord.FormKey);
                    break;

                case ConditionData.ParameterCategory.String:
                default:
                    throw new NotImplementedException();
                }
                switch (paramTypes.Second.GetCategory())
                {
                case ConditionData.ParameterCategory.None:
                case ConditionData.ParameterCategory.Number:
                    writer.Write(item.ParameterTwoNumber);
                    break;

                case ConditionData.ParameterCategory.Form:
                    FormKeyBinaryTranslation.Instance.Write(writer, item.ParameterTwoRecord.FormKey);
                    break;

                case ConditionData.ParameterCategory.String:
                default:
                    throw new NotImplementedException();
                }
                writer.Write(item.Unknown3);
                writer.Write(item.Unknown4);
                writer.Write(item.Unknown5);
            }
예제 #17
0
            static partial void WriteBinaryOwnerCustom(MutagenWriter writer, IExtraDataGetter item)
            {
                switch (item.Owner)
                {
                case NoOwner noOwner:
                    writer.Write(noOwner.RawOwnerData);
                    writer.Write(noOwner.RawVariableData);
                    break;

                case NpcOwner npcOwner:
                    FormKeyBinaryTranslation.Instance.Write(writer, npcOwner.Npc.FormKey);
                    FormKeyBinaryTranslation.Instance.Write(writer, npcOwner.Global.FormKey);
                    break;

                case FactionOwner factionOwner:
                    FormKeyBinaryTranslation.Instance.Write(writer, factionOwner.Faction.FormKey);
                    writer.Write(factionOwner.RequiredRank);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
예제 #18
0
파일: Climate.cs 프로젝트: Noggog/Mutagen
            static partial void WriteBinaryMoonAndPhaseLengthCustom(MutagenWriter writer, IClimateGetter item)
            {
                var raw = item.PhaseLength;

                if (item.Moons.HasFlag(Climate.Moon.Masser))
                {
                    raw = (byte)EnumExt.SetFlag(raw, ClimateBinaryCreateTranslation.MasserFlag, true);
                }
                if (item.Moons.HasFlag(Climate.Moon.Secunda))
                {
                    raw = (byte)EnumExt.SetFlag(raw, ClimateBinaryCreateTranslation.SecundaFlag, true);
                }
                writer.Write(raw);
            }
예제 #19
0
            static partial void WriteBinaryConditionsCustom(MutagenWriter writer, IMusicTrackGetter item)
            {
                var conditions = item.Conditions;

                if (conditions == null)
                {
                    return;
                }
                using (HeaderExport.Subrecord(writer, RecordTypes.CITC))
                {
                    writer.Write(conditions.Count);
                }
                ConditionBinaryWriteTranslation.WriteConditionsList(conditions, writer);
            }
예제 #20
0
 static partial void CustomBinaryEndExport(MutagenWriter writer, IDialogTopicGetter obj)
 {
     if (!obj.Items.TryGet(out var items) ||
         items.Count == 0)
     {
         return;
     }
     using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group))
     {
         FormKeyBinaryTranslation.Instance.Write(
             writer,
             obj.FormKey);
         writer.Write((int)GroupTypeEnum.TopicChildren);
         writer.Write(obj.Timestamp);
         Mutagen.Bethesda.Binary.ListBinaryTranslation <IDialogItemGetter> .Instance.Write(
             writer : writer,
             items : items,
             transl : (MutagenWriter subWriter, IDialogItemGetter subItem) =>
         {
             subItem.WriteToBinary(subWriter);
         });
     }
 }
예제 #21
0
            public static partial void WriteBinaryIDParseCustom(MutagenWriter writer, IQuestAliasGetter item)
            {
                RecordType type = item.Type switch
                {
                    QuestAlias.TypeEnum.Reference => RecordTypes.ALST,
                    QuestAlias.TypeEnum.Location => RecordTypes.ALLS,
                    _ => throw new NotImplementedException(),
                };

                using (HeaderExport.Subrecord(writer, type))
                {
                    writer.Write(item.ID);
                }
            }
예제 #22
0
            static partial void CustomBinaryEndExport(MutagenWriter writer, IWorldspaceGetter obj)
            {
                try
                {
                    var road     = obj.Road;
                    var topCell  = obj.TopCell;
                    var subCells = obj.SubCells;
                    if (subCells?.Count == 0 &&
                        road == null &&
                        topCell == null)
                    {
                        return;
                    }
                    using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group))
                    {
                        FormKeyBinaryTranslation.Instance.Write(
                            writer,
                            obj.FormKey);
                        writer.Write((int)GroupTypeEnum.WorldChildren);
                        writer.Write(obj.SubCellsTimestamp);

                        road?.WriteToBinary(writer);
                        topCell?.WriteToBinary(writer);
                        Mutagen.Bethesda.Binary.ListBinaryTranslation <IWorldspaceBlockGetter> .Instance.Write(
                            writer : writer,
                            items : subCells,
                            transl : (MutagenWriter subWriter, IWorldspaceBlockGetter subItem) =>
                        {
                            subItem.WriteToBinary(subWriter);
                        });
                    }
                }
                catch (Exception ex)
                {
                    throw RecordException.Enrich(ex, obj);
                }
            }
예제 #23
0
            public static partial void WriteBinaryAnimationsCustom(MutagenWriter writer, IPackageIdlesGetter item)
            {
                var anims = item.Animations;

                using (HeaderExport.Subrecord(writer, RecordTypes.IDLC))
                {
                    writer.Write(anims.Count, 1);
                }

                using (HeaderExport.Subrecord(writer, RecordTypes.IDLT))
                {
                    writer.Write(item.TimerSetting);
                }

                using (HeaderExport.Subrecord(writer, RecordTypes.IDLA))
                {
                    foreach (var anim in anims)
                    {
                        FormLinkBinaryTranslation.Instance.Write(
                            writer: writer,
                            item: anim);
                    }
                }
            }
예제 #24
0
            static partial void WriteBinaryCloudTexturesParseCustom(MutagenWriter writer, IWeatherGetter item)
            {
                var cloudTex = item.CloudTextures;

                for (int i = 0; i < cloudTex.Length; i++)
                {
                    if (!cloudTex[i].TryGet(out var tex))
                    {
                        continue;
                    }
                    using (HeaderExport.Subrecord(writer, new RecordType(WeatherBinaryCreateTranslation.TextureIntBase + i)))
                    {
                        writer.Write(tex, StringBinaryType.NullTerminate);
                    }
                }
            }
예제 #25
0
            public static partial void WriteBinaryCloudTexturesParseCustom(MutagenWriter writer, IWeatherGetter item)
            {
                var cloudTex = item.CloudTextures;

                for (int i = 0; i < cloudTex.Length; i++)
                {
                    if (cloudTex[i] is not {
                    } tex)
                    {
                        continue;
                    }
                    using (HeaderExport.Subrecord(writer, new RecordType(WeatherBinaryCreateTranslation.TextureIntBase + i)))
                    {
                        writer.Write(tex, StringBinaryType.NullTerminate, writer.MetaData.Encodings.NonTranslated);
                    }
                }
            }
예제 #26
0
        static Strings_Test()
        {
            _strs = new List <string>()
            {
                "Hello",
                "There",
                "Kind",
                "Sir"
            };

            _stringsFormat = new byte[100];
            MutagenWriter writer = new MutagenWriter(
                new BinaryWriter(new MemoryStream(_stringsFormat)),
                GameConstants.SkyrimLE);

            writer.Write((uint)_strs.Count);
            writer.Write((uint)_strs.Sum(s => s.Length + 1));
            int sum = 0;

            // Write index
            for (int i = 0; i < _strs.Count; i++)
            {
                writer.Write(i + 1);
                writer.Write(sum);
                sum += _strs[i].Length + 1;
            }
            // Write strings
            for (int i = 0; i < _strs.Count; i++)
            {
                writer.Write(_strs[i], StringBinaryType.NullTerminate);
            }

            _ILstringsFormat = new byte[100];
            writer           = new MutagenWriter(
                new BinaryWriter(new MemoryStream(_ILstringsFormat)),
                GameConstants.SkyrimLE);
            writer.Write((uint)_strs.Count);
            writer.Write((uint)_strs.Sum(s => s.Length + 5));
            sum = 0;
            // Write index
            for (int i = 0; i < _strs.Count; i++)
            {
                writer.Write(i + 1);
                writer.Write(sum);
                sum += _strs[i].Length + 5;
            }
            // Write strings
            for (int i = 0; i < _strs.Count; i++)
            {
                writer.Write(_strs[i].Length + 1);
                writer.Write(_strs[i], StringBinaryType.NullTerminate);
            }
        }
예제 #27
0
 public static void Write(
     this PrimitiveBinaryTranslation <bool, MutagenFrame, MutagenWriter> transl,
     MutagenWriter writer,
     bool item,
     RecordType header,
     byte byteLength)
 {
     try
     {
         using (HeaderExport.Header(writer, header, ObjectType.Subrecord))
         {
             writer.Write(item ? 1 : 0, byteLength);
         }
     }
     catch (Exception ex)
     {
         throw SubrecordException.Factory(ex, header);
     }
 }
예제 #28
0
            static partial void WriteBinaryTargetCustom(MutagenWriter writer, ILocationTargetRadiusGetter item)
            {
                var target = item.Target;

                switch (target)
                {
                case LocationTarget reference:
                    writer.Write((int)LocationTargetRadius.LocationType.NearReference);
                    FormKeyBinaryTranslation.Instance.Write(writer, reference.Link.FormKey);
                    break;

                case LocationCell cell:
                    writer.Write((int)LocationTargetRadius.LocationType.InCell);
                    FormKeyBinaryTranslation.Instance.Write(writer, cell.Link.FormKey);
                    break;

                case LocationObjectId id:
                    writer.Write((int)LocationTargetRadius.LocationType.ObjectID);
                    FormKeyBinaryTranslation.Instance.Write(writer, id.Link.FormKey);
                    break;

                case LocationObjectType type:
                    writer.Write((int)LocationTargetRadius.LocationType.ObjectType);
                    writer.Write((int)type.Type);
                    break;

                case LocationKeyword keyw:
                    writer.Write((int)LocationTargetRadius.LocationType.LinkedReference);
                    FormKeyBinaryTranslation.Instance.Write(writer, keyw.Link.FormKey);
                    break;

                case LocationFallback fallback:
                    writer.Write((int)fallback.Type);
                    writer.Write(fallback.Data);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
예제 #29
0
 public void Write(
     MutagenWriter writer,
     string item,
     RecordType header,
     StringBinaryType binaryType = StringBinaryType.NullTerminate)
 {
     try
     {
         using (HeaderExport.Header(writer, header, ObjectType.Subrecord))
         {
             writer.Write(
                 item,
                 binaryType: binaryType);
         }
     }
     catch (Exception ex)
     {
         throw SubrecordException.Enrich(ex, header);
     }
 }
예제 #30
0
            static partial void WriteBinaryFlagsCustom(MutagenWriter writer, IBookGetter item)
            {
                byte flags = (byte)item.Flags;

                switch (item.Teaches)
                {
                case BookSpell _:
                    flags = (byte)EnumExt.SetFlag(flags, BookBinaryCreateTranslation.SkillFlag, false);
                    flags = (byte)EnumExt.SetFlag(flags, BookBinaryCreateTranslation.SpellFlag, true);
                    break;

                case BookSkill _:
                    flags = (byte)EnumExt.SetFlag(flags, BookBinaryCreateTranslation.SkillFlag, true);
                    flags = (byte)EnumExt.SetFlag(flags, BookBinaryCreateTranslation.SpellFlag, false);
                    break;

                default:
                    break;
                }
                writer.Write(flags);
            }