Beispiel #1
0
        /// <summary>
        /// Add string with key to the end of the list, unless an index is given.
        /// If an index is given the key/value will be added at that index, and all keys/values after that index will be moved one slot
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void AddString(string key, string value, int index = -1)
        {
            GMD_Entry newEntry = new GMD_Entry {
                Key = key, Value = value
            };

            if (index == -1)
            {
                Entries.Add(newEntry);
            }
            else
            {
                Entries.Insert(index, newEntry);
            }
        }
Beispiel #2
0
        public GMD(string path) : base(path)
        {
            log.Info($"Loading '{path}'");

            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                using (BinaryReader br = new BinaryReader(fs))
                {
                    // Header
                    _header = br.ReadStruct <GMD_Header>();

                    if (_header.MagicString != "GMD")
                    {
                        throw new Exception("Not a GMD file!");
                    }

                    // Log some info about the GMD language
                    if (Enum.IsDefined(typeof(EmLanguage), _header.Language))
                    {
                        EmLanguage language = (EmLanguage)_header.Language;
                        log.Info("Language: " + language);
                    }
                    else
                    {
                        log.Warn($"Unknown language: 0x{_header.Language:X04} ({_header.Language})");
                    }

                    // Filename
                    Filename = br.ReadStringZero(ExEncoding.ASCII);

                    // Set Entries initial capacity
                    Entries = new List <IGMD_Entry>(_header.StringCount);

                    // Info Table
                    for (int i = 0; i < _header.KeyCount; i++)
                    {
                        GMD_Entry entry = new GMD_Entry {
                            InfoTableEntry = br.ReadStruct <GMD_InfoTableEntry>()
                        };

                        int lastStringIndex = 0;
                        if (Entries.OfType <GMD_Entry>().Count() > 0)
                        {
                            lastStringIndex = Entries.OfType <GMD_Entry>().Last().InfoTableEntry.StringIndex;
                        }

                        for (int j = lastStringIndex + 1; j < entry.InfoTableEntry.StringIndex; j++)
                        {
                            Entries.Add(new GMD_EntryWithoutKey());
                        }

                        Entries.Add(entry);
                    }

                    // If there are "Invalid Message" entries after the last valid entry then the above code won't add GMD_EntryWithoutKey's for those entries
                    // So here we add GMD_EntryWithoutKey entries till we have {StringCount} amount of them
                    for (int i = Entries.Count; i < _header.StringCount; i++)
                    {
                        Entries.Add(new GMD_EntryWithoutKey());
                    }

                    // Block with unknown data
                    _unk1 = br.ReadBytes(0x800);

                    // Keys, this skips over the GMD_EntryWithoutKey entries
                    foreach (GMD_Entry entry in Entries.OfType <GMD_Entry>())
                    {
                        entry.Key = br.ReadStringZero(ExEncoding.UTF8);
                    }

                    // Strings
                    string[] strings            = new string[_header.StringCount];
                    long     startOfStringBlock = fs.Position;

                    for (int i = 0; i < _header.StringCount; i++)
                    {
                        if (fs.Position == fs.Length)
                        {
                            log.Warn($"Expected to read {_header.StringCount - i} more strings (for a total of {_header.StringCount}). But we already are at the end of the stream!");
                            break;
                        }

                        strings[i] = br.ReadStringZero(ExEncoding.UTF8);
                    }

                    log.Info("Expected StringBlockSize = " + _header.StringBlockSize);
                    log.Info("Actual StringBlockSize = " + (fs.Position - startOfStringBlock));

                    if (_header.StringBlockSize != (fs.Position - startOfStringBlock))
                    {
                        log.Warn("Actual StringBlockSize is not the same as the expected StringBlockSize!");
                    }

                    for (int i = 0; i < _header.StringCount; i++)
                    {
                        Entries[i].Value = strings[i];
                    }
                }
        }