Exemplo n.º 1
0
 public void WriteNullable(
     MutagenWriter writer,
     ITranslatedStringGetter?item,
     RecordType header,
     StringBinaryType binaryType,
     StringsSource source)
 {
     if (item == null)
     {
         return;
     }
     try
     {
         using (HeaderExport.Header(writer, header, ObjectType.Subrecord))
         {
             if (writer.MetaData.StringsWriter == null)
             {
                 writer.Write(
                     item.String ?? string.Empty,
                     binaryType: binaryType);
             }
             else
             {
                 writer.Write(writer.MetaData.StringsWriter.Register(item, source));
             }
         }
     }
     catch (Exception ex)
     {
         throw SubrecordException.Factory(ex, header);
     }
 }
Exemplo n.º 2
0
        public uint Register(ITranslatedStringGetter str, StringsSource source)
        {
            List <KeyValuePair <Language, string>[]> strs = source switch
            {
                StringsSource.Normal => _strings,
                StringsSource.IL => _ilStrings,
                StringsSource.DL => _dlStrings,
                _ => throw new NotImplementedException(),
            };

            lock (strs)
            {
                // ToDo
                // Add Count member to TranslatedString, or something similar to short circuit array creation if unnecessary
                var arr = str.ToArray();
                if (!arr.Any(x => x.Value != null))
                {
                    // Do not insert into strings writer
                    return(0);
                }
                strs.Add(arr);
                try
                {
                    return(checked ((uint)strs.Count));
                }
                catch (OverflowException)
                {
                    throw new OverflowException("Too many translated strings for current system to handle.");
                }
            }
        }
Exemplo n.º 3
0
 public void WriteNullable(
     MutagenWriter writer,
     ITranslatedStringGetter?item,
     RecordType header,
     StringBinaryType binaryType,
     StringsSource source)
 {
     if (item == null)
     {
         return;
     }
     using (HeaderExport.Header(writer, header, ObjectType.Subrecord))
     {
         if (writer.MetaData.StringsWriter == null)
         {
             writer.Write(
                 item.String,
                 binaryType: binaryType);
         }
         else
         {
             writer.Write(writer.MetaData.StringsWriter.Register(item, source));
         }
     }
 }
Exemplo n.º 4
0
        public static bool TryRetrieveInfoFromString(ReadOnlySpan <char> name, out StringsSource source, out Language language, out ReadOnlySpan <char> modName)
        {
            source   = default;
            language = default;
            modName  = default;
            var extensionIndex = name.LastIndexOf('.');

            if (extensionIndex == -1)
            {
                return(false);
            }
            if (!TryConvertToStringSource(name.Slice(extensionIndex + 1), out source))
            {
                return(false);
            }
            var separatorIndex = name.LastIndexOf('_');

            if (separatorIndex == -1)
            {
                return(false);
            }
            if (separatorIndex > extensionIndex)
            {
                return(false);
            }
            var languageSpan = name.Slice(separatorIndex + 1, extensionIndex - separatorIndex - 1);

            modName = name.Slice(0, separatorIndex);
            return(Enum.TryParse(languageSpan.ToString(), ignoreCase: true, out language));
        }
Exemplo n.º 5
0
        public uint Register(ITranslatedStringGetter str, StringsSource source)
        {
            List <KeyValuePair <Language, string>[]> strs = source switch
            {
                StringsSource.Normal => _strings,
                StringsSource.IL => _ilStrings,
                StringsSource.DL => _dlStrings,
                _ => throw new NotImplementedException(),
            };

            lock (strs)
            {
                var arr = str.ToArray();
                if (!arr.Any(x => !string.IsNullOrEmpty(x.Value)))
                {
                    // Do not insert into strings writer
                    return(0);
                }
                strs.Add(arr);
                try
                {
                    return(checked ((uint)strs.Count));
                }
                catch (OverflowException)
                {
                    throw new OverflowException("Too many translated strings for current system to handle.");
                }
            }
        }
Exemplo n.º 6
0
        public uint Register(string str, Language language, StringsSource source)
        {
            List <KeyValuePair <Language, string>[]> strs = source switch
            {
                StringsSource.Normal => _strings,
                StringsSource.IL => _ilStrings,
                StringsSource.DL => _dlStrings,
                _ => throw new NotImplementedException(),
            };

            lock (strs)
            {
                strs.Add(new KeyValuePair <Language, string>[]
                {
                    new KeyValuePair <Language, string>(language, str)
                });
                try
                {
                    return(checked ((uint)strs.Count));
                }
                catch (OverflowException)
                {
                    throw new OverflowException("Too many translated strings for current system to handle.");
                }
            }
        }
Exemplo n.º 7
0
 public static string GetFileName(
     StringsLanguageFormat languageFormat,
     ModKey modKey,
     Language language,
     StringsSource source)
 {
     return($"{modKey.Name}_{GetLanguageString(languageFormat, language)}.{GetSourceString(source)}");
 }
Exemplo n.º 8
0
 private Dictionary <Language, Lazy <IStringsLookup> > Get(StringsSource source)
 {
     return(source switch
     {
         StringsSource.Normal => _strings,
         StringsSource.IL => _ilstrings,
         StringsSource.DL => _dlstrings,
         _ => throw new NotImplementedException(),
     });
Exemplo n.º 9
0
 public Dictionary <Language, Lazy <IStringsLookup> > Get(StringsSource source)
 {
     return(source switch
     {
         StringsSource.Normal => Strings,
         StringsSource.IL => IlStrings,
         StringsSource.DL => DlStrings,
         _ => throw new NotImplementedException(),
     });
Exemplo n.º 10
0
 public bool Parse(
     MutagenFrame frame,
     StringsSource source,
     StringBinaryType binaryType,
     out TranslatedString item,
     bool parseWhole = true)
 {
     item = Parse(frame, source, binaryType, parseWhole);
     return(true);
 }
Exemplo n.º 11
0
        /// <inheritdoc />
        public bool TryLookup(StringsSource source, Language language, uint key, [MaybeNullWhen(false)] out string str)
        {
            var dict = Get(source);

            if (!dict.TryGetValue(language, out var lookup))
            {
                str = default;
                return(false);
            }
            return(lookup.Value.TryLookup(key, out str));
        }
Exemplo n.º 12
0
        public static StringsFileFormat GetFormat(StringsSource source)
        {
            switch (source)
            {
            case StringsSource.Normal:
                return(StringsFileFormat.Normal);

            case StringsSource.IL:
            case StringsSource.DL:
                return(StringsFileFormat.LengthPrepended);

            default:
                throw new NotImplementedException();
            }
        }
Exemplo n.º 13
0
 public void Write(
     MutagenWriter writer,
     ITranslatedStringGetter item,
     RecordType header,
     StringBinaryType binaryType,
     StringsSource source)
 {
     using (HeaderExport.Header(writer, header, ObjectType.Subrecord))
     {
         Write(
             writer,
             item,
             binaryType,
             source);
     }
 }
Exemplo n.º 14
0
        public static string GetSourceString(StringsSource source)
        {
            switch (source)
            {
            case StringsSource.Normal:
                return(StringsFileExtension);

            case StringsSource.IL:
                return(ILStringsFileExtension);

            case StringsSource.DL:
                return(DLStringsFileExtension);

            default:
                throw new NotImplementedException();
            }
        }
Exemplo n.º 15
0
 public void Write(
     MutagenWriter writer,
     ITranslatedStringGetter item,
     StringBinaryType binaryType,
     StringsSource source)
 {
     if (writer.MetaData.StringsWriter == null)
     {
         writer.Write(
             item.String,
             binaryType: binaryType);
     }
     else
     {
         writer.Write(writer.MetaData.StringsWriter.Register(item, source));
     }
 }
Exemplo n.º 16
0
 public static bool TryConvertToStringSource(ReadOnlySpan <char> str, out StringsSource source)
 {
     if (str.Equals(StringsFileExtension, StringComparison.OrdinalIgnoreCase))
     {
         source = StringsSource.Normal;
         return(true);
     }
     if (str.Equals(ILStringsFileExtension, StringComparison.OrdinalIgnoreCase))
     {
         source = StringsSource.IL;
         return(true);
     }
     if (str.Equals(DLStringsFileExtension, StringComparison.OrdinalIgnoreCase))
     {
         source = StringsSource.DL;
         return(true);
     }
     source = default;
     return(false);
 }
Exemplo n.º 17
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));
     }
 }
Exemplo n.º 18
0
 public void Write(
     MutagenWriter writer,
     ITranslatedStringGetter item,
     RecordType header,
     StringBinaryType binaryType,
     StringsSource source)
 {
     try
     {
         using (HeaderExport.Header(writer, header, ObjectType.Subrecord))
         {
             Write(
                 writer,
                 item,
                 binaryType,
                 source);
         }
     }
     catch (Exception ex)
     {
         throw SubrecordException.Factory(ex, header);
     }
 }
Exemplo n.º 19
0
 public TranslatedString Parse(
     ReadOnlyMemorySlice <byte> data,
     StringsSource source,
     IStringsFolderLookup?lookup)
 {
     if (lookup != null)
     {
         if (data.Length != 4)
         {
             throw new ArgumentException($"String in Strings File format had unexpected length: {data.Length} != 4");
         }
         uint key = BinaryPrimitives.ReadUInt32LittleEndian(data);
         if (key == 0)
         {
             return(string.Empty);
         }
         return(lookup.CreateString(source, key));
     }
     else
     {
         return(BinaryStringUtility.ProcessWholeToZString(data));
     }
 }
Exemplo n.º 20
0
 public virtual TranslatedString Parse(
     MutagenFrame frame,
     StringsSource source,
     StringBinaryType stringBinaryType,
     bool parseWhole = true)
 {
     if (frame.MetaData.StringsLookup != null)
     {
         if (frame.Remaining != 4)
         {
             throw new ArgumentException($"String in Strings File format had unexpected length: {frame.Remaining} != 4");
         }
         uint key = frame.ReadUInt32();
         if (key == 0)
         {
             return(string.Empty);
         }
         return(frame.MetaData.StringsLookup.CreateString(source, key));
     }
     else
     {
         return(Parse(frame, parseWhole, stringBinaryType));
     }
 }
Exemplo n.º 21
0
 public TranslatedString Parse(
     MutagenFrame reader,
     StringsSource source,
     StringBinaryType stringBinaryType,
     bool parseWhole = true)
 {
     if (reader.MetaData.StringsLookup != null)
     {
         if (reader.Remaining != 4)
         {
             throw new ArgumentException($"String in Strings File format had unexpected length: {reader.Remaining} != 4");
         }
         uint key = reader.ReadUInt32();
         if (key == 0)
         {
             return(new TranslatedString(directString: null));
         }
         return(reader.MetaData.StringsLookup.CreateString(source, key));
     }
     else
     {
         return(Parse(reader, parseWhole, stringBinaryType));
     }
 }
Exemplo n.º 22
0
 private async Task ProcessStringsFilesIndices(
     Func <IMutagenReadStream> streamGetter,
     DirectoryInfo dataFolder,
     Language language,
     StringsSource source,
     ModKey modKey,
     HashSet <uint> knownDeadKeys,
     IEnumerable <string> bsaOrder)
 {
     using var stream = streamGetter();
     switch (source)
     {
     case StringsSource.Normal:
         ProcessStringsFiles(
             GameRelease.Fallout4,
             modKey,
             dataFolder,
             language,
             StringsSource.Normal,
             strict: false,
             knownDeadKeys: knownDeadKeys,
             bsaOrder: bsaOrder,
             RenumberStringsFileEntries(
                 GameRelease.Fallout4,
                 modKey,
                 stream,
                 dataFolder,
                 language,
                 StringsSource.Normal,
                 new StringsAlignmentCustom("GMST", GameSettingStringHandler),
                 new RecordType[] { "KYWD", "FULL" }
                 ));
         break;
         //case StringsSource.DL:
         //    ProcessStringsFiles(
         //        modKey,
         //        dataFolder,
         //        language,
         //        StringsSource.DL,
         //        strict: true,
         //        RenumberStringsFileEntries(
         //            modKey,
         //            stream,
         //            dataFolder,
         //            language,
         //            StringsSource.DL,
         //            new RecordType[] { "SCRL", "DESC" },
         //        ));
         //    break;
         //case StringsSource.IL:
         //    ProcessStringsFiles(
         //        modKey,
         //        dataFolder,
         //        language,
         //        StringsSource.IL,
         //        strict: true,
         //        RenumberStringsFileEntries(
         //            modKey,
         //            stream,
         //            dataFolder,
         //            language,
         //            StringsSource.IL,
         //            new RecordType[] { "DIAL" },
         //            new RecordType[] { "INFO", "NAM1" }
         //        ));
         //    break;
     }
 }
Exemplo n.º 23
0
        private async Task ProcessStringsFilesIndices(Func <IMutagenReadStream> streamGetter, DirectoryInfo dataFolder, Language language, StringsSource source, ModKey modKey)
        {
            using var stream = streamGetter();
            switch (source)
            {
            case StringsSource.Normal:
                ProcessStringsFiles(
                    modKey,
                    dataFolder,
                    language,
                    StringsSource.Normal,
                    strict: true,
                    RenumberStringsFileEntries(
                        modKey,
                        stream,
                        dataFolder,
                        language,
                        StringsSource.Normal,
                        new StringsAlignmentCustom("GMST", GameSettingStringHandler),
                        new RecordType[] { "LSCR", "DESC" },
                        new RecordType[] { "ACTI", "FULL", "RNAM" },
                        new RecordType[] { "APPA", "FULL" },
                        new RecordType[] { "AMMO", "FULL" },
                        new RecordType[] { "ARMO", "FULL" },
                        new RecordType[] { "BOOK", "FULL" },
                        new RecordType[] { "CLAS", "FULL" },
                        new RecordType[] { "EYES", "FULL" },
                        new RecordType[] { "CONT", "FULL" },
                        new RecordType[] { "DOOR", "FULL" },
                        new RecordType[] { "FACT", "FULL", "MNAM", "FNAM" },
                        new RecordType[] { "FURN", "FULL" },
                        new RecordType[] { "HAZD", "FULL" },
                        new RecordType[] { "HDPT", "FULL" },
                        new RecordType[] { "ALCH", "FULL" },
                        new RecordType[] { "INGR", "FULL" },
                        new RecordType[] { "LIGH", "FULL" },
                        new RecordType[] { "MGEF", "FULL", "DNAM" },
                        new RecordType[] { "MISC", "FULL" },
                        new RecordType[] { "MSTT", "FULL" },
                        new RecordType[] { "NPC_", "FULL", "SHRT" },
                        new RecordType[] { "ENCH", "FULL" },
                        new RecordType[] { "PROJ", "FULL" },
                        new RecordType[] { "RACE", "FULL" },
                        new RecordType[] { "SCRL", "FULL" },
                        new RecordType[] { "SLGM", "FULL" },
                        new RecordType[] { "SPEL", "FULL" },
                        new RecordType[] { "TACT", "FULL" },
                        new RecordType[] { "TREE", "FULL" },
                        new RecordType[] { "WEAP", "FULL" },
                        new RecordType[] { "FLOR", "FULL", "RNAM" },
                        new RecordType[] { "KEYM", "FULL" },
                        new RecordType[] { "CELL", "FULL" },
                        new RecordType[] { "REFR", "FULL" },
                        new RecordType[] { "WRLD", "FULL" },
                        new RecordType[] { "DIAL", "FULL" },
                        new RecordType[] { "INFO", "RNAM" },
                        new RecordType[] { "QUST", "FULL", "NNAM" },
                        new RecordType[] { "WATR", "FULL" },
                        new RecordType[] { "EXPL", "FULL" },
                        new StringsAlignmentCustom("PERK", PerkStringHandler),
                        new RecordType[] { "BPTD", "BPTN" },
                        new RecordType[] { "AVIF", "FULL" },
                        new RecordType[] { "LCTN", "FULL" },
                        new RecordType[] { "MESG", "FULL", "ITXT" },
                        new RecordType[] { "WOOP", "FULL", "TNAM" },
                        new RecordType[] { "SHOU", "FULL" },
                        new RecordType[] { "SNCT", "FULL" },
                        new RecordType[] { "CLFM", "FULL" },
                        new RecordType[] { "REGN", "RDMP" }
                        ));
                break;

            case StringsSource.DL:
                ProcessStringsFiles(
                    modKey,
                    dataFolder,
                    language,
                    StringsSource.DL,
                    strict: true,
                    RenumberStringsFileEntries(
                        modKey,
                        stream,
                        dataFolder,
                        language,
                        StringsSource.DL,
                        new RecordType[] { "SCRL", "DESC" },
                        new RecordType[] { "APPA", "DESC" },
                        new RecordType[] { "AMMO", "DESC" },
                        new RecordType[] { "ARMO", "DESC" },
                        new RecordType[] { "ALCH", "DESC" },
                        new RecordType[] { "WEAP", "DESC" },
                        new RecordType[] { "BOOK", "DESC", "CNAM" },
                        new RecordType[] { "QUST", "CNAM" },
                        new RecordType[] { "PERK", "DESC" },
                        new RecordType[] { "AVIF", "DESC" },
                        new RecordType[] { "MESG", "DESC" },
                        new RecordType[] { "SHOU", "DESC" },
                        new RecordType[] { "COLL", "DESC" },
                        new RecordType[] { "RACE", "DESC" },
                        new RecordType[] { "SPEL", "DESC" }
                        ));
                break;

            case StringsSource.IL:
                ProcessStringsFiles(
                    modKey,
                    dataFolder,
                    language,
                    StringsSource.IL,
                    strict: true,
                    RenumberStringsFileEntries(
                        modKey,
                        stream,
                        dataFolder,
                        language,
                        StringsSource.IL,
                        new RecordType[] { "DIAL" },
                        new RecordType[] { "INFO", "NAM1" }
                        ));
                break;
            }
        }
Exemplo n.º 24
0
        private void WriteStrings(List <KeyValuePair <Language, string>[]> strs, StringsSource source)
        {
            if (strs.Count == 0)
            {
                return;
            }
            WriteDir.Create();

            var subLists = new Dictionary <Language, List <(string String, int Index)> >();

            for (int i = 0; i < strs.Count; i++)
            {
                var item = strs[i];
                foreach (var lang in item)
                {
                    if (!subLists.TryGetValue(lang.Key, out var list))
                    {
                        list = new List <(string String, int Index)>();
                        subLists[lang.Key] = list;
                    }
                    list.Add((lang.Value, i + 1));
                }
            }

            foreach (var language in subLists)
            {
                using var writer = new MutagenWriter(
                          Path.Combine(WriteDir.Path, StringsUtility.GetFileName(_modKey, language.Key, source)),
                          meta: null !);
                // Write count
                writer.Write(language.Value.Count);
                // Write filler for length later
                writer.WriteZeros(4);
                // Write Directory
                int size = 0;
                foreach (var item in language.Value)
                {
                    writer.Write(item.Index);
                    switch (source)
                    {
                    case StringsSource.Normal:
                        writer.Write(size);
                        size += item.String.Length + 1;
                        break;

                    case StringsSource.IL:
                    case StringsSource.DL:
                        writer.Write(size);
                        size += item.String.Length + 5;
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
                // Go back and write content length;
                var pos = writer.Position;
                writer.Position = 4;
                writer.Write(size);
                writer.Position = pos;
                // Write strings
                foreach (var item in language.Value)
                {
                    switch (source)
                    {
                    case StringsSource.Normal:
                        writer.Write(item.String, StringBinaryType.NullTerminate);
                        break;

                    case StringsSource.IL:
                    case StringsSource.DL:
                        writer.Write(item.String.Length + 1);
                        writer.Write(item.String, StringBinaryType.NullTerminate);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
        }
Exemplo n.º 25
0
 public static string GetFileName(ModKey modKey, Language language, StringsSource source)
 {
     return($"{modKey.Name}_{language}.{GetSourceString(source)}");
 }
Exemplo n.º 26
0
 /// <summary>
 /// Overlays onto a set of bytes assumed to be in Strings file format
 /// </summary>
 /// <param name="data">Data to wrap</param>
 /// <param name="source">Source type</param>
 public StringsLookupOverlay(ReadOnlyMemorySlice <byte> data, StringsSource source)
 {
     Init(data, StringsUtility.GetFormat(source));
 }
Exemplo n.º 27
0
 /// <summary>
 /// Reads all bytes from a file, and overlays them
 /// </summary>
 /// <param name="path">Path to read in</param>
 /// <param name="source">Source type</param>
 public StringsLookupOverlay(string path, StringsSource source)
 {
     Init(File.ReadAllBytes(path), StringsUtility.GetFormat(source));
 }
Exemplo n.º 28
0
 public ManualStringsLookup(
     StringsSource source,
     params (Language Language, uint Key, string Str)[] strs)