예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkManagerAsync"/> class.
        /// </summary>
        /// <param name="connection"><see cref="Socket"/> to wrap.</param>
        /// <param name="networkHandler"><see cref="PacketReceivedHandler"/> that will handle incoming packet.</param>
        /// <param name="packetReceivedFailedHandler"><see cref="PacketReceivedFailedHandler"/> that will handle incoming packet that failed to read.</param>
        /// <exception cref="System.ArgumentNullException"/>
        public NetworkManagerAsync(Socket connection,
                                   PacketReceivedHandler packetReceivedHandler,
                                   PacketReceivedFailedHandler packetReceivedFailedHandler)
        {
            if (PacketDictionary == null)  // could a use a static constructor?
            {
                InitializePacketDictionary();
            }
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }
            if (packetReceivedHandler == null)
            {
                throw new ArgumentNullException("packetReceivedHandler");
            }


            Connection           = connection;
            PacketReceived       = packetReceivedHandler;
            PacketReceivedFailed = packetReceivedFailedHandler;
            CoCCrypto            = new CoCCrypto();
            ReceiveEventPool     = new SocketAsyncEventArgsPool(25);
            SendEventPool        = new SocketAsyncEventArgsPool(25);
            StartReceive(ReceiveEventPool.Pop());
        }
예제 #2
0
        public IPacket ReadPacket(out byte[] rawPacket, out byte[] decryptedPacket)
        {
            /* Receive data from the socket, saves it a buffer,
             * then reads packet from the buffer.
             */

            var timeout = DateTime.Now.AddMilliseconds(500); // 500ms

            while (DataAvailable && DateTime.Now < timeout)
            {
                CoCStream.ReadToBuffer(); // reads data saves it a buffer

                //var packetBuffer = new PacketBuffer(CoCStream.ReadBuffer.ToArray());
                var enPacketReader = new PacketReader(CoCStream.ReadBuffer);

                // read header
                var packetID      = enPacketReader.ReadUInt16();
                var packetLength  = enPacketReader.ReadInt24();
                var packetVersion = enPacketReader.ReadUInt16();

                // read body
                if (packetLength > enPacketReader.BaseStream.Length) // check if data is enough data is avaliable in the buffer
                {
                    continue;
                }

                var encryptedData = GetPacketBody(packetLength);
                var decryptedData = (byte[])encryptedData.Clone(); // cloning just cause we want the encrypted data

                CoCCrypto.Decrypt(decryptedData);

                var dePacketReader = new PacketReader(new MemoryStream(decryptedData));

                var packet = CreatePacketInstance(packetID);
                if (packet is UnknownPacket)
                {
                    packet = new UnknownPacket
                    {
                        ID      = packetID,
                        Length  = packetLength,
                        Version = packetVersion
                    };
                    ((UnknownPacket)packet).EncryptedData = encryptedData;
                }

                decryptedPacket = decryptedData;
                rawPacket       = ExtractRawPacket(packetLength);
                //CoCStream.ReadBuffer = new MemoryStream(4096);
                //CoCStream.Write(packetBuffer.Buffer, 0, packetBuffer.Buffer.Length);
                try
                {
                    packet.ReadPacket(dePacketReader);
                }
                catch { }
                return(packet);
            }
            decryptedPacket = null;
            rawPacket       = null;
            return(null);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkManagerAsync"/> class.
        /// </summary>
        /// <param name="connection"><see cref="Socket"/> to wrap.</param>
        /// <param name="networkHandler"><see cref="PacketReceivedHandler"/> that will handle incoming packet.</param>
        /// <param name="packetReceivedFailedHandler"><see cref="PacketReceivedFailedHandler"/> that will handle incoming packet that failed to read.</param>
        /// <exception cref="System.ArgumentNullException"/>
        public NetworkManagerAsync(Socket connection,
                                   PacketReceivedHandler packetReceivedHandler,
                                   PacketReceivedFailedHandler packetReceivedFailedHandler)
        {
            if (PacketDictionary == null)  // could a use a static constructor?
            {
                InitializePacketDictionary();
            }
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }
            if (packetReceivedHandler == null)
            {
                throw new ArgumentNullException("packetReceivedHandler");
            }


            Connection           = connection;
            PacketReceived       = packetReceivedHandler;
            PacketReceivedFailed = packetReceivedFailedHandler;
            Seed             = MathHelper.Random.Next(); // must make this moar flexible
            CoCCrypto        = new CoCCrypto();
            ReceiveEventPool = new SocketAsyncEventArgsPool(25);
            SendEventPool    = new SocketAsyncEventArgsPool(25);
            StartReceive();
        }
예제 #4
0
        public ProxyNetworkManager(Socket connection)
        {
            if (PacketDictionary == null)
                InitializePacketDictionary();

            Connection = connection;
            CoCStream = new CoCStream(connection);
            CoCCrypto = new CoCCrypto();
        }
예제 #5
0
        private void UpdateCiphers(int seed, byte[] key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            CoCCrypto.UpdateCiphers((ulong)seed, key);
        }
예제 #6
0
        public ProxyNetworkManager(Socket connection)
        {
            if (PacketDictionary == null)
            {
                InitializePacketDictionary();
            }

            Connection = connection;
            CoCStream  = new CoCStream(connection);
            CoCCrypto  = new CoCCrypto();
        }
        public void WritePacket(IPacket packet)
        {
            /* Writes packet to a buffer,
             * then sends the buffer to the socket
             */
            MemoryStream tempStream = new MemoryStream();

            packet.WritePacket(new PacketWriter(tempStream));
            byte[] buffer = new byte[tempStream.Length];
            tempStream.Read(buffer, 0, buffer.Length);
            buffer = (buffer.Skip(HeaderSize).ToArray());
            CoCCrypto.Encrypt(buffer);
            CoCStream.Write(buffer, 0, buffer.Length);
        }
예제 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkManagerAsync"/> class.
        /// </summary>
        /// <param name="connection"><see cref="Socket"/> to wrap.</param>
        /// <exception cref="ArgumentNullException"/>
        public NetworkManagerAsync(Socket connection)
        {
            if (connection == null)
                throw new ArgumentNullException("connection");

            Connection = connection;
            Settings = new NetworkManagerAsyncSettings(); // default settings
            CoCCrypto = new CoCCrypto();
            ReceiveEventPool = new SocketAsyncEventArgsPool(25);
            SendEventPool = new SocketAsyncEventArgsPool(25);
            SetAsyncOperationPools();

            StartReceive(ReceiveEventPool.Pop());
        }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkManagerAsync"/> class.
        /// </summary>
        /// <param name="connection"><see cref="Socket"/> to wrap.</param>
        /// <exception cref="ArgumentNullException"/>
        public NetworkManagerAsync(Socket connection)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }

            Connection       = connection;
            Settings         = new NetworkManagerAsyncSettings(); // default settings
            CoCCrypto        = new CoCCrypto();
            ReceiveEventPool = new SocketAsyncEventArgsPool(25);
            SendEventPool    = new SocketAsyncEventArgsPool(25);
            SetAsyncOperationPools();

            StartReceive(ReceiveEventPool.Pop());
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkManagerAsync"/> class.
        /// </summary>
        /// <param name="connection"><see cref="Socket"/> to wrap.</param>
        /// <param name="networkHandler"><see cref="PacketReceivedHandler"/> that will handle incoming packet.</param>
        /// <param name="packetReceivedFailedHandler"><see cref="PacketReceivedFailedHandler"/> that will handle incoming packet that failed to read.</param>
        /// <exception cref="System.ArgumentNullException"/>
        public NetworkManagerAsync(Socket connection,
                              PacketReceivedHandler packetReceivedHandler,
                              PacketReceivedFailedHandler packetReceivedFailedHandler)
        {
            if (PacketDictionary == null)  // could a use a static constructor?
                InitializePacketDictionary();
            if (connection == null)
                throw new ArgumentNullException("connection");
            if (packetReceivedHandler == null)
                throw new ArgumentNullException("packetReceivedHandler");

            Connection = connection;
            PacketReceived = packetReceivedHandler;
            PacketReceivedFailed = packetReceivedFailedHandler;
            CoCCrypto = new CoCCrypto();
            ReceiveEventPool = new SocketAsyncEventArgsPool(25);
            SendEventPool = new SocketAsyncEventArgsPool(25);
            StartReceive(ReceiveEventPool.Pop());
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NetworkManagerAsync"/> class.
        /// </summary>
        /// <param name="connection"><see cref="Socket"/> to wrap.</param>
        /// <param name="networkHandler"><see cref="PacketReceivedHandler"/> that will handle incoming packet.</param>
        /// <param name="packetReceivedFailedHandler"><see cref="PacketReceivedFailedHandler"/> that will handle incoming packet that failed to read.</param>
        /// <exception cref="System.ArgumentNullException"/>
        public NetworkManagerAsync(Socket connection,
                              PacketReceivedHandler packetReceivedHandler,
                              PacketReceivedFailedHandler packetReceivedFailedHandler)
        {
            if (PacketDictionary == null)  // could a use a static constructor?
                InitializePacketDictionary();
            if (connection == null)
                throw new ArgumentNullException("connection");
            if (packetReceivedHandler == null)
                throw new ArgumentNullException("packetReceivedHandler");

            Connection = connection;
            PacketReceived = packetReceivedHandler;
            PacketReceivedFailed = packetReceivedFailedHandler;
            Seed = MathHelper.Random.Next(); // must make this moar flexible
            CoCCrypto = new CoCCrypto();
            ReceiveEventPool = new SocketAsyncEventArgsPool(25);
            SendEventPool = new SocketAsyncEventArgsPool(25);
            StartReceive();
        }
예제 #12
0
        /// <summary>
        /// Sends the specified packet to the socket asynchronously.
        /// </summary>
        /// <param name="packet">The <see cref="IPacket"/> that will be sent.</param>
        /// <exception cref="System.ArgumentNullException"/>
        public void SendPacket(IPacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }

            using (var dePacketWriter = new PacketWriter(new MemoryStream()))
            {
                packet.WritePacket(dePacketWriter);
                var body = ((MemoryStream)dePacketWriter.BaseStream).ToArray();
                CoCCrypto.Encrypt(body);

                if (packet is UpdateKeyPacket)
                {
                    UpdateCiphers(Seed, ((UpdateKeyPacket)packet).Key);           // handle update key packet
                }
                using (var enPacketWriter = new PacketWriter(new MemoryStream())) // write header
                {
                    enPacketWriter.WriteUInt16(packet.ID);
                    enPacketWriter.WriteInt24(body.Length);
                    enPacketWriter.WriteUInt16(0); // the unknown or the packet version
                    enPacketWriter.Write(body, 0, body.Length);

                    var rawPacket = ((MemoryStream)enPacketWriter.BaseStream).ToArray();

                    // should avoid new objs
                    var args = new SocketAsyncEventArgs();
                    args.SetBuffer(rawPacket, 0, rawPacket.Length);
                    if (!Connection.SendAsync(args))
                    {
                        AsyncOperationCompleted(Connection, args);
                    }
                }
            }
        }
예제 #13
0
 public void UpdateCiphers(ulong seed, byte[] key)
 {
     CoCCrypto.UpdateCiphers(seed, key);
 }
예제 #14
0
        private IPacket[] ProcessReceive(SocketAsyncEventArgs args)
        {
            var packetList     = new List <IPacket>();
            var packetToken    = args.UserToken as PacketToken;
            var bytesToProcess = args.BytesTransferred;

            if (bytesToProcess == 0)
            {
                //TODO: Fire event
                Disconnected = true;
                return(null);
            }

ReadPacket:

            // read header
            if (packetToken.HeaderReceiveOffset != PacketBuffer.HeaderSize) // we do not have the header
            {
                if (PacketBuffer.HeaderSize > bytesToProcess)               // we got less that 7 bytes, some parts of the header
                {
                    Console.WriteLine("[Net:ID {0}] Not enough bytes to read header.", packetToken.TokenID);

                    Buffer.BlockCopy(args.Buffer, packetToken.ReceiveOffset, packetToken.Header, packetToken.HeaderReceiveOffset, bytesToProcess);
                    packetToken.HeaderReceiveOffset += bytesToProcess;
                    packetToken.ReceiveOffset        = 0;
                    StartReceive(args);
                    return(packetList.ToArray());
                }
                else // if we got more than enough data for the header
                {
                    Buffer.BlockCopy(args.Buffer, packetToken.ReceiveOffset, packetToken.Header, packetToken.HeaderReceiveOffset, PacketBuffer.HeaderSize);
                    packetToken.HeaderReceiveOffset += PacketBuffer.HeaderSize;
                    packetToken.ReceiveOffset       += PacketBuffer.HeaderSize; // probs here?
                    bytesToProcess -= PacketBuffer.HeaderSize;
                    ReadHeader(packetToken);
                }
            }

            // read body
            if (packetToken.BodyReceiveOffset != packetToken.Length)
            {
                if (packetToken.Length - packetToken.BodyReceiveOffset > bytesToProcess) // if we dont have enough to read body
                {
                    Console.WriteLine("[Net:ID {0}] Not enough bytes to read body.", packetToken.TokenID);

                    Buffer.BlockCopy(args.Buffer, packetToken.ReceiveOffset, packetToken.Body, packetToken.BodyReceiveOffset, bytesToProcess);
                    packetToken.BodyReceiveOffset += bytesToProcess;
                    packetToken.ReceiveOffset      = 0;
                    StartReceive(args);
                    return(packetList.ToArray());
                }
                else // if we got more than enough data for the body
                {
                    Buffer.BlockCopy(args.Buffer, packetToken.ReceiveOffset, packetToken.Body, packetToken.BodyReceiveOffset, packetToken.Length - packetToken.BodyReceiveOffset);
                    bytesToProcess                -= packetToken.Length - packetToken.BodyReceiveOffset;
                    packetToken.ReceiveOffset     += packetToken.Length - packetToken.BodyReceiveOffset;
                    packetToken.BodyReceiveOffset += packetToken.Length;
                }
            }

            var packet       = CreatePacketInstance(packetToken.ID);
            var packetDeData = (byte[])packetToken.Body.Clone();

            CoCCrypto.Decrypt(packetDeData);

            if (packet is UnknownPacket)
            {
                packet = new UnknownPacket()
                {
                    ID            = packetToken.ID,
                    Length        = packetToken.Length,
                    Version       = packetToken.Version,
                    EncryptedData = packetToken.Body,
                    DecryptedData = packetDeData
                };
            }

            using (var reader = new PacketReader(new MemoryStream(packetDeData)))
            {
                try
                {
                    if (!(packet is UnknownPacket))
                    {
                        packet.ReadPacket(reader);
                    }
                }
                catch (Exception ex)
                {
                    if (PacketReceivedFailed != null)
                    {
                        PacketReceivedFailed(args, ex);
                    }
                    packetToken.Reset();
                    goto ReadPacket;
                }
            }

            if (packet is UpdateKeyPacket)
            {
                UpdateCiphers(Seed, ((UpdateKeyPacket)packet).Key);
            }

            packetList.Add(packet);
            packetToken.Reset();
            if (bytesToProcess != 0)
            {
                goto ReadPacket;
            }

            packetToken.ReceiveOffset = 0;
            ReceiveEventPool.Push(args);
            StartReceive(ReceiveEventPool.Pop());
            return(packetList.ToArray());
        }
예제 #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public IPacket[] ReadPackets(SocketAsyncEventArgs args)
        {
            var list = new List <IPacket>();
            var numBytesToProcess = args.BytesTransferred;

            if (numBytesToProcess == 0)
            {
                return(null);
            }

            while (true)
            {
                if (numBytesToProcess == 0)
                {
                    break;
                }

                var packet       = (IPacket)null;
                var packetBuffer = args.UserToken as PacketBuffer;
                try
                {
                    using (var enPacketReader = new PacketReader(new MemoryStream(packetBuffer.Buffer)))
                    {
                        if (PacketBuffer.HeaderSize > numBytesToProcess) // check if there is a header
                        {
                            break;
                        }

                        // read header
                        var packetID      = enPacketReader.ReadUInt16();
                        var packetLength  = enPacketReader.ReadInt24();
                        var packetVersion = enPacketReader.ReadUInt16(); // the unknown

                        // read body
                        if (packetLength > numBytesToProcess) // check if data is enough data is avaliable in the buffer
                        {
                            break;
                        }

                        var encryptedData = packetBuffer.ExtractPacket(PacketExtractionFlags.Body |
                                                                       PacketExtractionFlags.Remove,
                                                                       packetLength);
                        var decryptedData = (byte[])encryptedData.Clone(); // cloning just cause we want the encrypted data
                        CoCCrypto.Decrypt(decryptedData);
                        numBytesToProcess -= packetLength + PacketBuffer.HeaderSize;

                        using (var dePacketReader = new PacketReader(new MemoryStream(decryptedData)))
                        {
                            packet = CreatePacketInstance(packetID);
                            if (packet is UnknownPacket)
                            {
                                packet = new UnknownPacket
                                {
                                    ID            = packetID,
                                    Length        = packetLength,
                                    Version       = packetVersion,
                                    EncryptedData = encryptedData,
                                    DecryptedData = decryptedData
                                };
                            }
                            packet.ReadPacket(dePacketReader);
                        }
                    }
                    if (packet is UpdateKeyPacket)
                    {
                        UpdateCiphers(Seed, ((UpdateKeyPacket)packet).Key); // handle update key packet
                    }
                    list.Add(packet);
                }
                catch (Exception ex)
                {
                    if (PacketReceivedFailed != null)
                    {
                        PacketReceivedFailed(args, ex);
                    }
                }
            }
            return(list.ToArray());
        }