Example #1
0
            public static void ReadCsf(Csf csf, Stream stream, SageGame game)
            {
                using (var reader = new BinaryReader(stream, Encoding.ASCII, true))
                {
                    var magic = reader.ReadInt32();
                    if (magic != _magicCsf)
                    {
                        throw new InvalidDataException("Error parsing csf (Magic: CSF expected).");
                    }
                    var version    = reader.ReadInt32();
                    var numLabels  = reader.ReadInt32();
                    var numStrings = reader.ReadInt32();
                    if (numLabels != numStrings)
                    {
                        // throw new NotSupportedException("Csf substrings are not supported.");
                        logger.Warn("[CSF] Number of labels and strings mismatch.");
                    }
                    csf._numStrings = numStrings;
                    reader.ReadUInt32(); // reserved
                    var    languageCode = reader.ReadUInt32();
                    string language;
                    switch (game)
                    {
                    case SageGame.CncGenerals:
                    case SageGame.CncGeneralsZeroHour:
                        language = ((LanguageGenerals)languageCode).GetName();
                        break;

                    case SageGame.Bfme:
                    case SageGame.Bfme2:
                    case SageGame.Bfme2Rotwk:
                        language = ((LanguageBFME)languageCode).GetName();
                        break;

                    case SageGame.Cnc3:
                    case SageGame.Cnc3KanesWrath:
                        language = ((LanguageCnC3)languageCode).GetName();
                        break;

                    default:
                        language = "en-US";
                        break;
                    }
                    if (language is null)
                    {
                        language = "en-US";
                        logger.Warn($"Unknown language id {languageCode} for game {game}.");
                    }
                    csf._language = language;
                    string label;
                    int    strCount;
                    string str;
                    int    colonIdx;
                    string categoryLabel;
                    for (var idx = 0; idx < numLabels; ++idx)
                    {
                        magic = reader.ReadInt32();
                        if (magic != _magicLabel)
                        {
                            throw new InvalidDataException("Error parsing csf (Magic: LBL expected).");
                        }
                        strCount = reader.ReadInt32();
                        label    = reader.ReadUInt32PrefixedAsciiString();
                        for (var idy = 0; idy < strCount; ++idy)
                        {
                            magic = reader.ReadInt32();
                            if (magic != _magicLString && magic != _magicLWideString)
                            {
                                throw new InvalidDataException("Error parsing csf (Magic: STR/STRW expected).");
                            }
                            if (idy == 0)
                            {
                                str = reader.ReadUInt32PrefixedNegatedUnicodeString();
                                if (magic == _magicLWideString)
                                {
                                    str += reader.ReadUInt32PrefixedAsciiString();
                                }
                                colonIdx = label.IndexOf(':');
                                if (colonIdx == -1)
                                {
                                    categoryLabel = string.Empty;
                                    logger.Warn($"Empty category found for {label}.");
                                }
                                else
                                {
                                    categoryLabel = label.Substring(0, colonIdx).ToUpperInvariant();
                                }
                                if (!csf._strings.TryGetValue(categoryLabel, out var category))
                                {
                                    category = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                                    csf._strings.Add(categoryLabel, category);
                                }
                                label = label.Substring(colonIdx + 1);
                                if (category.ContainsKey(label))
                                {
                                    logger.Warn($"[CSF] String duplication: '{categoryLabel}:{label}' -> '{category[label]}', new value: '{str}'");
                                }
                                else
                                {
                                    category.Add(label, str);
                                }
                            }
                            else
                            {
                                if (magic == _magicLString)
                                {
                                    logger.Info($"[CSF] Skipping substring '{reader.ReadUInt32PrefixedNegatedUnicodeString()}' from {label}.");
                                }
                                else
                                {
                                    logger.Info($"[CSF] Skipping substring '{reader.ReadUInt32PrefixedNegatedUnicodeString()}{reader.ReadUInt32PrefixedAsciiString()}' from {label}.");
                                }
                            }
                        }
                    }
                }
            }
Example #2
0
 public CsfTranslationProvider(Stream stream, SageGame game)
 {
     Debug.Assert(!(stream is null), $"{nameof(stream)} is null");
     _csf = new Csf();
     Csf.ReadCsf(_csf, stream, game);
 }