예제 #1
0
        private static BaseMessage Instantiate(Type classType, RT_MSG_TYPE id, byte[] plain)
        {
            BaseMessage msg = null;

            //
            using (MemoryStream stream = new MemoryStream(plain))
            {
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    if (classType == null)
                    {
                        msg = new RawMessage(id);
                    }
                    else
                    {
                        msg = (BaseMessage)Activator.CreateInstance(classType);
                    }

                    try
                    {
                        msg.Deserialize(reader);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine($"Error deserializing {id} {BitConverter.ToString(plain)}");
                        Console.WriteLine(e);
                    }
                }
            }

            return(msg);
        }
예제 #2
0
        /// <summary>
        /// Whether or not the given rt message id should be logged
        /// </summary>
        public bool IsLog(RT_MSG_TYPE msgId)
        {
            if (_rtLogFilters.TryGetValue(msgId, out var result))
            {
                return(result);
            }

            return(false);
        }
예제 #3
0
        public static void RegisterMessage(RT_MSG_TYPE id, Type type)
        {
            // Init first
            Initialize();

            // Set or overwrite.
            if (!_messageClassById.ContainsKey(id))
            {
                _messageClassById.Add(id, type);
            }
            else
            {
                _messageClassById[id] = type;
            }
        }
예제 #4
0
        public static BaseScertMessage Instantiate(RT_MSG_TYPE id, byte[] hash, byte[] messageBuffer, Func <RT_MSG_TYPE, CipherContext, ICipher> getCipherCallback = null)
        {
            // Init first
            Initialize();

            BaseScertMessage msg = null;

            // Get class
            if (!_messageClassById.TryGetValue(id, out var classType))
            {
                classType = null;
            }

            // Decrypt
            if (hash != null)
            {
                CipherContext context = (CipherContext)(hash[3] >> 5);
                var           cipher  = getCipherCallback(id, context);
                if (cipher == null)
                {
                    return(null);
                }

                if (cipher.Decrypt(messageBuffer, hash, out var plain))
                {
                    msg = Instantiate(classType, id, plain);
                }

                // This is a hack to make the dme server connect
                // We don't really care what their key is since we're not encrypting our response
                else if (id == RT_MSG_TYPE.RT_MSG_CLIENT_CRYPTKEY_PUBLIC)
                {
                    msg = Instantiate(classType, id, plain);
                }
                else
                {
                    Logger.Error($"Unable to decrypt {id}, HASH:{BitConverter.ToString(hash)} DATA:{BitConverter.ToString(messageBuffer)} CIPHER:{cipher}");
                }
            }
            else
            {
                msg = Instantiate(classType, id, messageBuffer);
            }

            return(msg);
        }
예제 #5
0
 /// <summary>
 /// Whether or not the given RT message id should be logged
 /// </summary>
 public bool IsLog(RT_MSG_TYPE msgType)
 {
     return(_rtLogFilters.TryGetValue(msgType, out var r) && r);
 }
예제 #6
0
 public MessageAttribute(RT_MSG_TYPE id)
 {
     MessageId = id;
 }
예제 #7
0
 public RawMessage(RT_MSG_TYPE id)
 {
     _id = id;
 }
예제 #8
0
        public static List <BaseMessage> Instantiate(byte[] messageBuffer, int index, int size, Func <RT_MSG_TYPE, CipherContext, ICipher> getCipherCallback = null)
        {
            // Init first
            Initialize();

            List <BaseMessage> msgs = new List <BaseMessage>();
            BaseMessage        msg  = null;

            //
            using (MemoryStream stream = new MemoryStream(messageBuffer, index, size))
            {
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    while (reader.BaseStream.CanRead && reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        // Reset
                        msg = null;
                        long start = reader.BaseStream.Position;

                        // Parse header
                        byte        rawId     = reader.ReadByte();
                        RT_MSG_TYPE id        = (RT_MSG_TYPE)(rawId & 0x7F);
                        bool        encrypted = rawId >= 0x80;
                        ushort      len       = reader.ReadUInt16();

                        // End
                        if (len > (reader.BaseStream.Length - reader.BaseStream.Position))
                        {
                            break;
                        }

                        // Get class
                        if (!_messageClassById.TryGetValue(id, out var classType))
                        {
                            classType = null;
                        }

                        // Decrypt
                        if (encrypted && len > 0)
                        {
                            byte[]        hash       = reader.ReadBytes(4);
                            byte[]        cipherText = reader.ReadBytes(len);
                            CipherContext context    = (CipherContext)(hash[3] >> 5);
                            var           cipher     = getCipherCallback(id, context);

                            if (cipher.Decrypt(cipherText, hash, out var plain))
                            {
                                msg = Instantiate(classType, id, plain);
                            }
                            // This is a hack to make the dme server connect
                            // We don't really care what their key is since we're not encrypting our response
                            else if (id == RT_MSG_TYPE.RT_MSG_CLIENT_CRYPTKEY_PUBLIC)
                            {
                                msg = new RT_MSG_CLIENT_CRYPTKEY_PUBLIC();
                            }
                            else
                            {
                                Console.WriteLine($"Unable to decrypt {id} {len}, HASH:{BitConverter.ToString(hash)} DATA:{BitConverter.ToString(cipherText)}");
                            }
                        }
                        else
                        {
                            msg = Instantiate(classType, id, reader.ReadBytes(len));
                        }

                        if (msg != null)
                        {
                            msgs.Add(msg);
                        }
                    }
                }
            }

            return(msgs);
        }