Beispiel #1
0
        protected override void Init(Server server)
        {
            m_Server = server;

            m_RSACryptoPrivate = new RSACryptoServiceProvider(RSAKeySize);
            m_RSACryptoPrivate.PersistKeyInCsp = false;

            m_SendPacketSerial    = 0;
            m_ReceivePacketSerial = 0;

            IgeNetStream stream = GetStream();

            stream.CalculateChecksums = true;
            m_WriterStream            = new BinaryWriter(stream);

            m_CanProcessPackets.Reset();
            (m_PacketReceiverThread = new Thread(PacketReceiverThread)).Start(GetStream());

            base.Init(server);
        }
Beispiel #2
0
        private void SendNonBlocking(Packet packet)
        {
            PacketEncryptionMethod encryption = packet.Encryption;

            lock (SyncSend) {
                if (m_WriterStream == null || !Connected)
                {
                    throw new IOException("Client is not connected");
                }

                IgeNetStream stream = (IgeNetStream)m_WriterStream.BaseStream;

                if (GameDebugger.MinNetLogLevel <= LogLevel.VerboseDebug)
                {
                    Log(LogLevel.VerboseDebug, "Sending packet: '{0}'. Packet contents: {1}", packet.GetType().FullName, packet.ToString());
                }
                else
                {
                    Log(LogLevel.Debug, "Sending packet: '{0}'", packet.GetType().FullName);
                }

                // Log(LogLevel.Debug, "Resetting send checksum");
                // stream.ResetWriteChecksum();

                //Thread.MemoryBarrier();

                Log(LogLevel.Debug, "Sending packet id: 0x{0:X8}", packet.Id);
                m_WriterStream.Write(packet.Id);

                switch (encryption)
                {
                case PacketEncryptionMethod.RSA: {
                    Log(LogLevel.Debug, "Serializing packet to a RSA encrypted block");
                    using (BinaryWriter cryptoWriter = new BinaryWriter(new MemoryStream(), Encoding.Unicode)) {
                        packet.Serialize(cryptoWriter);
                        byte[] cryptoData = m_RSACryptoPublic.Encrypt(((MemoryStream)cryptoWriter.BaseStream).ToArray(), false);
                        Log(LogLevel.Debug, "Encrypted serialized block size: {0}", cryptoData.Length);
                        m_WriterStream.Write(cryptoData.Length);
                        m_WriterStream.Write(cryptoData);
                    }
                    break;
                }

                case PacketEncryptionMethod.Rijndael: {
                    Log(LogLevel.Debug, "Serializing packet to a Rijndael crypto stream");
                    using (MemoryStream mem = new MemoryStream()) {
                        using (BinaryWriter cryptoWriter = new BinaryWriter(new CryptoStream(mem, m_RijCrypto.CreateEncryptor(), CryptoStreamMode.Write), Encoding.Unicode)) {
                            packet.Serialize(cryptoWriter);
                        }
                        byte[] cryptoData = mem.ToArray();
                        Log(LogLevel.Debug, "Encrypted serialized block size: {0}", cryptoData.Length);
                        m_WriterStream.Write(cryptoData.Length);
                        m_WriterStream.Write(cryptoData);
                    }
                    break;
                }

                default: {
                    Log(LogLevel.Debug, "Serializing packet to a write stream");
                    packet.Serialize(m_WriterStream);
                    break;
                }
                }

                uint checksum = stream.WriteChecksum ^ unchecked (m_SendPacketSerial++);

                //Thread.MemoryBarrier();

                Log(LogLevel.Debug, "Sending checksum: 0x{0:X8}", checksum);
                m_WriterStream.Write(checksum);

                //Thread.MemoryBarrier();

                Log(LogLevel.Debug, "Packet sending done");
            }
        }
Beispiel #3
0
        private void PacketReceiverThread(object param)
        {
            IgeNetStream stream = (IgeNetStream)param;

            Log(LogLevel.Debug, "PacketReceiverThread: start");
            try {
                using (BinaryReader reader = new BinaryReader(stream)) {
                    Packet packet;
                    uint   packetId, checksum, checksum2;
                    ((IgeNetStream)reader.BaseStream).CalculateChecksums = true;
                    while (true)
                    {
                        // Log(LogLevel.Debug, "PacketReceiverThread: resetting read checksum");
                        // stream.ResetReadChecksum();

                        //Thread.MemoryBarrier();

                        Log(LogLevel.Debug, "PacketReceiverThread: reading packet id");
                        packetId = reader.ReadUInt32();

                        Log(LogLevel.Debug, "PacketReceiverThread: creating packet 0x{0:X8} instance", packetId);
                        packet = Packet.CreateInstance(packetId);

                        switch (packet.Encryption)
                        {
                        case PacketEncryptionMethod.RSA: {
                            int cryptoSize = reader.ReadInt32();
                            Log(LogLevel.Debug, "PacketReceiverThread: deserializing packet 0x{0:X8} from an RSA encrypted block ({1} bytes)", packetId, cryptoSize);
                            using (BinaryReader cryptoReader = new BinaryReader(new MemoryStream(m_RSACryptoPrivate.Decrypt(reader.ReadBytes(cryptoSize), false)), Encoding.Unicode)) {
                                packet.Deserialize(cryptoReader);
                            }
                            break;
                        }

                        case PacketEncryptionMethod.Rijndael: {
                            int cryptoSize = reader.ReadInt32();
                            Log(LogLevel.Debug, "PacketReceiverThread: deserializing packet 0x{0:X8} from a Rijndael crypto stream ({1} bytes)", packetId, cryptoSize);
                            using (MemoryStream mem = new MemoryStream(reader.ReadBytes(cryptoSize))) {
                                using (BinaryReader cryptoReader = new BinaryReader(new CryptoStream(mem, m_RijCrypto.CreateDecryptor(), CryptoStreamMode.Read), Encoding.Unicode)) {
                                    packet.Deserialize(cryptoReader);
                                }
                            }
                            break;
                        }

                        default: {
                            Log(LogLevel.Debug, "PacketReceiverThread: deserializing packet  0x{0:X8} from a read stream", packetId);
                            packet.Deserialize(reader);
                            break;
                        }
                        }

                        if (GameDebugger.MinNetLogLevel <= LogLevel.VerboseDebug)
                        {
                            Log(LogLevel.VerboseDebug, "PacketReceiverThread: received packet '{0}'. Packet contents: {1}", packet.GetType().FullName, packet.ToString());
                        }
                        else
                        {
                            Log(LogLevel.Debug, "PacketReceiverThread: received packet '{0}'", packet.GetType().FullName);
                        }

                        //Thread.MemoryBarrier();

                        // packet.Deserialize(reader);
                        checksum = stream.ReadChecksum ^ unchecked (m_ReceivePacketSerial++);

                        //Thread.MemoryBarrier();

                        checksum2 = reader.ReadUInt32();

                        //Thread.MemoryBarrier();

                        Log(LogLevel.Debug, "PacketReceiverThread: comparing checksums (calculated=0x{0:X8}; received=0x{1:X8})", checksum, checksum2);
                        if (checksum != checksum2)
                        {
                            Disconnect();
                            throw new UserFriendlyException("The protocol might be broken or some packet serializer and deserializer don't match each other.", "Connection error");
                        }

                        MethodInfo method;
                        if (packet is RSAServerPublicKeyPacket || packet is RSAClientPublicKeyPacket || packet is RijndaelEncryptionKeyPacket)
                        {
                            Log(LogLevel.Debug, "PacketReceiverThread: searching for handler method in IGE.Net.Client");
                            method = typeof(Client).GetMethod("OnPacketReceived", BindingFlags.ExactBinding | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { packet.GetType() }, null);
                        }
                        else
                        {
                            m_CanProcessPackets.WaitOne();                             // block any non encryption key exchange packets
                            Log(LogLevel.Debug, "PacketReceiverThread: searching for handler method in derived class");
                            method = GetType().GetMethod("OnPacketReceived", BindingFlags.ExactBinding | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { packet.GetType() }, null);
                        }

                        if (method != null)
                        {
                            Log(LogLevel.Debug, "PacketReceiverThread: invoking custom packet received event");
                            method.Invoke(this, new object[] { packet });
                        }
                        else
                        {
                            Log(LogLevel.Debug, "PacketReceiverThread: invoking default packet received event");
                            OnPacketReceived(packet);
                        }

                        if (PacketReceivedEvent != null)
                        {
                            PacketReceivedEvent.Invoke(this, new PacketReceivedEventArgs(packet));
                        }
                    }
                }
            }
            catch (Exception ex) {
                Log(LogLevel.Debug, "PacketReceiverThread exception: {0}", ex.ToString());
            }
            finally {
                stream.Dispose();
            }
            Log(LogLevel.Debug, "PacketReceiverThread: end");
        }