Example #1
0
        /// <summary>
        /// Replaces Unicode symbols from message.bin with human readable text tokens
        /// </summary>
        /// <param name="text">Encoded text</param>
        public string UnicodeDecode(string text)
        {
            var sb        = new StringBuilder();
            var textBytes = Encoding.Unicode.GetBytes(text);

            for (int i = 0; i < textBytes.Length; i += 2)
            {
                ushort shortCharacter = BitConverter.ToUInt16(textBytes, i);
                if (EntriesByUnicode.TryGetValue(shortCharacter, out var entry))
                {
                    // A direct match for the character was found
                    sb.Append($"[{entry.CodeString}]");
                }
                else if (EntriesByUnicode.TryGetValue((ushort)(shortCharacter & 0xFF00), out entry))
                {
                    // A match for the low bytes was found, which means that it encodes some other value.
                    // The amount of words to decode is found in the Length.
                    uint encodedValue = shortCharacter & 0xFFu;
                    if (entry.Length > 0)
                    {
                        encodedValue = 0;
                        for (int j = 0; j < entry.Length; j++)
                        {
                            i += (j + 1) * 2;

                            uint partialValue = BitConverter.ToUInt16(textBytes, i);
                            encodedValue |= partialValue << (j * 2);
                        }
                        encodedValue--;
                    }

                    string encodedValueString;
                    if (ConstantReplacementTable.TryGetValue(entry.CodeString, out var enumType))
                    {
                        encodedValueString = Enum.GetName(enumType, encodedValue) ?? encodedValue.ToString();
                    }
                    else
                    {
                        encodedValueString = encodedValue.ToString();
                    }
                    sb.Append($"[{entry.CodeString}{encodedValueString}]");
                }
                else
                {
                    sb.Append(Encoding.Unicode.GetString(textBytes, i, 2));
                }
            }
            return(sb.ToString());
        }
Example #2
0
        /// <summary>
        /// Replaces special text tokens with Unicode symbols for message.bin
        /// </summary>
        /// <param name="text">User-friendly text</param>
        public string UnicodeEncode(string text)
        {
            var sb = new StringBuilder();

            var match         = StringTokenRegex.Match(text);
            int lastStringPos = 0;

            while (match.Success)
            {
                sb.Append(text.Substring(lastStringPos, match.Index - lastStringPos));
                string directive   = match.Groups[1].Value;
                string?valueString = match.Groups.Count > 1 ? match.Groups[2].Value : null;

                if (!string.IsNullOrEmpty(valueString) && EntriesByCodeString.TryGetValue(directive + valueString, out var entry))
                {
                    // Sometimes the directive and value are both included (e.g. [M:B01])
                    sb.Append((char)entry.UnicodeValue);
                }
                else if (EntriesByCodeString.TryGetValue(directive, out entry))
                {
                    ushort unicodeValue = entry.UnicodeValue;
                    if (entry.DigitFlag && valueString != null)
                    {
                        uint value;
                        if (ConstantReplacementTable.TryGetValue(entry.CodeString, out var enumType))
                        {
                            value = Convert.ToUInt32(Enum.Parse(enumType, valueString));
                        }
                        else
                        {
                            value = uint.Parse(valueString);
                        }

                        // Encode the value into the two low bytes.
                        // It seems like one of the bytes inside the value is encoded redundantly.
                        unicodeValue = (ushort)((unicodeValue & 0xFF00) | (byte)value);
                        sb.Append((char)unicodeValue);

                        if (entry.Length > 0)
                        {
                            if (entry.Length > 2)
                            {
                                throw new Exception("Invalid entry length.");
                            }

                            byte[] bytes = BitConverter.GetBytes(value + 1);
                            sb.Append(Encoding.Unicode.GetString(bytes, 0, entry.Length * 2));
                        }
                    }
                    else
                    {
                        sb.Append((char)unicodeValue);
                    }
                }
                else
                {
                    sb.Append(match.Value);
                }
                lastStringPos = match.Index + match.Length;
                match         = match.NextMatch();
            }

            sb.Append(text.Substring(lastStringPos, text.Length - lastStringPos));
            return(sb.ToString());
        }