Beispiel #1
0
 internal static int InternalizeStrings(Plugin plugin)
 {
     bool anyModified = false;
     int count = 0;
     foreach (var record in plugin.Enumerate().OfType<Record>())
     {
         record.MatchRecordStructureToRecord();
         foreach (var sr in record.SubRecords)
         {
             var elements = record.EnumerateElements(sr, rawData: true).ToList();
             foreach (var elem in elements)
             {
                 if (elem.Structure != null && elem.Structure.type == ElementValueType.LString)
                 {
                     var data = elem.Data;
                     uint id = TypeConverter.h2i(data);
                     if (id == 0) continue;
                     if (data.Count == 4)
                     {
                         var str = plugin.LookupFormStrings(id);
                         if (!string.IsNullOrEmpty(str))
                         {
                             elem.AssignValue<ArraySegment<byte>>(new ArraySegment<byte>(TypeConverter.str2h(str)));
                             ++count;
                         }
                     }
                 }
             }
             if (elements.Any(x => x.Changed))
             {
                 // need to repack the structure
                 using (var ms = new MemoryStream(sr.GetReadonlyData().Length))
                 {
                     foreach (var seg in elements.Select(elem => elem.Data))
                         ms.Write(seg.Array, seg.Offset, seg.Count);
                     sr.SetData(ms.ToArray());
                 }
                 anyModified = true;
             }
         }
     }
     if (anyModified)
     {
         var tes4 = plugin.Records.OfType<Record>().FirstOrDefault(x => x.Name == "TES4");
         if (tes4 != null) tes4.Flags1 &= ~0x00000080U;
     }
     return count;
 }
Beispiel #2
0
        /// <summary>
        /// Extract any internalized strings and put in string table
        /// </summary>
        /// <param name="plugin"></param>
        public static int ExtractInternalStrings(Plugin plugin)
        {
            int count = 0;
            // uint maxid = plugin.Masters.Max(x=>x.Strings.Count > 0 ? x.Strings.Keys.Max() : 0); // No need to check the masters string since the numbers are unique for every plugin

            bool anyModified = false;
            foreach (var record in plugin.Enumerate().OfType<Record>())
            {
                record.MatchRecordStructureToRecord();
                foreach (var sr in record.SubRecords)
                {
                    var elements = record.EnumerateElements(sr, rawData: true).ToList();
                    foreach (var elem in elements)
                    {
                        if (elem.Structure != null && elem.Structure.type == ElementValueType.LString)
                        {
                            var data = elem.Data;
                            uint id = TypeConverter.h2i(data);
                            if (id == 0) continue;
                            if (data.Count == 4 && TypeConverter.IsLikelyString(data))
                            {
                                string str;
                                if (plugin.Strings.TryGetValue(id, out str))
                                    continue;
                            }
                            if (data.Count != 4 || TypeConverter.IsLikelyString(data))
                            {
                                string value = TypeConverter.GetString(data);
                                if (!String.IsNullOrEmpty(value))
                                {
                                    // uint nextid = Math.Max(maxid, plugin.Strings.Count == 0 ? 0 : plugin.Strings.Keys.Max()) + 1; // No need to check the masters strings since the numbers are unique for every plugin
                                    uint nextid = (plugin.Strings.Count == 0 ? 0 : plugin.Strings.Keys.Max()) + 1;
                                    int idx = plugin.Strings.FindValue(value);
                                    if (idx >= 0)
                                    {
                                        nextid = plugin.Strings.ElementAt(idx).Key;
                                    }
                                    else
                                    {
                                        plugin.Strings[nextid] = value;                                        
                                    }
                                    elem.AssignValue<ArraySegment<byte>>(
                                        new ArraySegment<byte>((byte[])TypeConverter.i2h(nextid).Clone()));
                                    ++count;
                                }
                            }
                        }
                    }
                    if (elements.Any(x => x.Changed))
                    {
                        // need to repack the structure
                        using (var ms = new MemoryStream(sr.GetReadonlyData().Length))
                        {
                            foreach (var seg in elements.Select(elem => elem.Data))
                                ms.Write(seg.Array, seg.Offset, seg.Count);
                            sr.SetData(ms.ToArray());
                        }
                        anyModified = true;
                    }
                }
            }
            if (anyModified)
            {
                var tes4 = plugin.Records.OfType<Record>().FirstOrDefault(x => x.Name == "TES4");
                if (tes4 != null) tes4.Flags1 |= 0x00000080U;
            }
            return count;
        }