/// <summary>
        /// Initializes a new instance of the <see cref="NetworkGateway"/> class.
        /// </summary>
        public static void Initialize()
        {
            if (NetworkTcp.Initialized)
            {
                return;
            }

            NetworkTcp.FillPools();

            NetworkTcp.Listener          = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            NetworkTcp.Listener.NoDelay  = true;
            NetworkTcp.Listener.Blocking = false;

            NetworkTcp.Initialized = true;

            NetworkTcp.Listener.Bind(new IPEndPoint(IPAddress.Any, 9339));
            NetworkTcp.Listener.Listen(150);

            Logging.Info(typeof(NetworkTcp), "Listener has been bound to " + NetworkTcp.Listener.LocalEndPoint + ".");

            SocketAsyncEventArgs AcceptEvent = new SocketAsyncEventArgs();

            AcceptEvent.Completed            += NetworkTcp.OnAcceptCompleted;
            AcceptEvent.DisconnectReuseSocket = true;

            NetworkTcp.StartAccept(AcceptEvent);
        }
        /// <summary>
        /// Processes to send a <see cref="Message"/> using the specified <see cref="SocketAsyncEventArgs"/>.
        /// </summary>
        /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param>
        private static void ProcessSend(SocketAsyncEventArgs AsyncEvent)
        {
            NetworkToken Token = (NetworkToken)AsyncEvent.UserToken;

            if (AsyncEvent.SocketError == SocketError.Success)
            {
                if (AsyncEvent.Count > AsyncEvent.BytesTransferred)
                {
                    int Offset = AsyncEvent.Offset + AsyncEvent.BytesTransferred;

                    if (Token.IsConnected)
                    {
                        AsyncEvent.SetBuffer(Offset, AsyncEvent.Buffer.Length - Offset);

                        if (!Token.Socket.SendAsync(AsyncEvent))
                        {
                            NetworkTcp.ProcessSend(AsyncEvent);
                        }

                        return;
                    }

                    NetworkTcp.Disconnect(Token.AsyncEvent);
                }
            }
            else
            {
                NetworkTcp.Disconnect(Token.AsyncEvent);
            }

            NetworkTcp.OnSendCompleted(null, AsyncEvent);
        }
 /// <summary>
 /// Starts to receive data from remote host.
 /// </summary>
 public static void StartReceive(NetworkToken Token)
 {
     if (!Token.Socket.ReceiveAsync(Token.AsyncEvent))
     {
         NetworkTcp.ProcessReceive(Token.AsyncEvent);
     }
 }
        /// <summary>
        /// Accept the new client and store it in memory.
        /// </summary>
        /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param>
        private static void ProcessAccept(SocketAsyncEventArgs AsyncEvent)
        {
            if (AsyncEvent.AcceptSocket.Connected)
            {
                string IpAddress = ((IPEndPoint)AsyncEvent.AcceptSocket.RemoteEndPoint).Address.ToString();

                if (IpAddress.StartsWith("192.168."))
                {
                    SocketAsyncEventArgs ReadEvent = NetworkTcp.ReadPool.Dequeue();

                    if (ReadEvent != null)
                    {
                        NetworkToken Token  = new NetworkToken(ReadEvent, AsyncEvent.AcceptSocket);
                        Device       Device = new Device(Token);

                        Devices.Add(Device);

                        if (!Token.Socket.ReceiveAsync(ReadEvent))
                        {
                            NetworkTcp.ProcessReceive(ReadEvent);
                        }
                    }
                    else
                    {
                        Logging.Warning(typeof(NetworkTcp), "Server is full, new connections cannot be accepted.");
                    }
                }
            }

            NetworkTcp.StartAccept(AsyncEvent);
        }
        /// <summary>
        /// Accepts a TCP Request.
        /// </summary>
        /// <param name="AcceptEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param>
        private static void StartAccept(SocketAsyncEventArgs AcceptEvent)
        {
            AcceptEvent.AcceptSocket   = null;
            AcceptEvent.RemoteEndPoint = null;

            if (!NetworkTcp.Listener.AcceptAsync(AcceptEvent))
            {
                NetworkTcp.OnAcceptCompleted(null, AcceptEvent);
            }
        }
 /// <summary>
 /// Called when [receive completed].
 /// </summary>
 /// <param name="Sender">The sender.</param>
 /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param>
 private static void OnReceiveCompleted(object Sender, SocketAsyncEventArgs AsyncEvent)
 {
     if (AsyncEvent.SocketError == SocketError.Success)
     {
         NetworkTcp.ProcessReceive(AsyncEvent);
     }
     else
     {
         NetworkTcp.Disconnect(AsyncEvent);
     }
 }
 /// <summary>
 /// Called when the client has been connected.
 /// </summary>
 /// <param name="Sender">The sender.</param>
 /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param>
 private static void OnConnectCompleted(object Sender, SocketAsyncEventArgs AsyncEvent)
 {
     if (AsyncEvent.SocketError == SocketError.Success)
     {
         ((ManualResetEventSlim)AsyncEvent.UserToken).Set();
     }
     else
     {
         NetworkTcp.Disconnect(AsyncEvent);
     }
 }
 /// <summary>
 /// Called when the client has been accepted.
 /// </summary>
 /// <param name="Sender">The sender.</param>
 /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param>
 private static void OnAcceptCompleted(object Sender, SocketAsyncEventArgs AsyncEvent)
 {
     if (AsyncEvent.SocketError == SocketError.Success)
     {
         NetworkTcp.ProcessAccept(AsyncEvent);
     }
     else
     {
         NetworkTcp.StartAccept(AsyncEvent);
     }
 }
        /// <summary>
        /// Connets the specified token to the remote host.
        /// </summary>
        public static bool StartConnect(string Host, out NetworkToken Token)
        {
            Socket Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            Socket.Blocking = false;
            Socket.NoDelay  = true;

            var ConnectEvent = new SocketAsyncEventArgs();

            ConnectEvent.RemoteEndPoint = new DnsEndPoint(Host, 9339);

            ManualResetEventSlim Waiter = new ManualResetEventSlim();

            ConnectEvent.Completed += NetworkTcp.OnConnectCompleted;
            ConnectEvent.UserToken  = Waiter;

            if (!Socket.ConnectAsync(ConnectEvent))
            {
                NetworkTcp.OnConnectCompleted(Socket, ConnectEvent);
            }

            if (Waiter.Wait(10000))
            {
                var AsyncEvent = NetworkTcp.ReadPool.Dequeue();

                if (AsyncEvent != null)
                {
                    Token = new NetworkToken(AsyncEvent, ConnectEvent.ConnectSocket);

                    Token.AsyncEvent.AcceptSocket   = null;
                    Token.AsyncEvent.RemoteEndPoint = new DnsEndPoint(Host, 9339);

                    if (!Token.Socket.ReceiveAsync(Token.AsyncEvent))
                    {
                        NetworkTcp.ProcessReceive(Token.AsyncEvent);
                    }

                    return(true);
                }
                else
                {
                    Logging.Info(typeof(NetworkTcp), "AsyncEvent == null at StartConnect().");
                }
            }
            else
            {
                Logging.Info(typeof(NetworkTcp), "Waiter.Wait(10000) != true at StartConnect().");
            }

            Token = null;

            return(false);
        }
Exemple #10
0
        /// <summary>
        /// Finalizes this instance.
        /// </summary>
        public void Process()
        {
            byte[] Buffer = this.Packet.ToArray();

            if (Buffer.Length >= 7)
            {
                this.TcpProcess(Buffer);
            }
            else
            {
                NetworkTcp.Disconnect(this.AsyncEvent);
            }
        }
        /// <summary>
        /// Receives data from the specified client.
        /// </summary>
        /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param>
        private static void ProcessReceive(SocketAsyncEventArgs AsyncEvent)
        {
            if (AsyncEvent.BytesTransferred == 0)
            {
                NetworkTcp.Disconnect(AsyncEvent);
            }

            if (AsyncEvent.SocketError != SocketError.Success)
            {
                NetworkTcp.Disconnect(AsyncEvent);
            }

            NetworkToken Token = (NetworkToken)AsyncEvent.UserToken;

            if (Token.IsConnected)
            {
                Token.AddData();

                try
                {
                    if (Token.Socket.Available == 0)
                    {
                        Token.Process();
                    }

                    if (Token.IsFailing == false)
                    {
                        if (!Token.Socket.ReceiveAsync(AsyncEvent))
                        {
                            NetworkTcp.ProcessReceive(AsyncEvent);
                        }
                    }
                    else
                    {
                        NetworkTcp.Disconnect(AsyncEvent);
                    }
                }
                catch (Exception Exception)
                {
                    Logging.Warning(typeof(NetworkTcp), Exception.GetType().Name + " thrown at ProcessReceive(" + AsyncEvent.RemoteEndPoint + ").");
                    NetworkTcp.Disconnect(AsyncEvent);
                }
            }
            else
            {
                NetworkTcp.Disconnect(AsyncEvent);
            }
        }
        /// <summary>
        /// Sends the specified message.
        /// </summary>
        /// <param name="Message">The message.</param>
        public void SendMessage(Message Message)
        {
            if (this.Device.Token.IsConnected)
            {
                if (Message.IsServerToClientMessage == false)
                {
                    Message.Encode();

                    byte[] Decrypted = Message.Stream.ToArray();
                    byte[] Encrypted = null;

                    if (this.SendEncrypter != null)
                    {
                        Encrypted = this.SendEncrypter.Encrypt(Decrypted);
                    }
                    else
                    {
                        if (this.PepperInit.State > 0)
                        {
                            if (this.PepperInit.State == 2)
                            {
                                this.PepperInit.ServerPublicKey = PepperFactory.PublicKey;
                                Encrypted = PepperCrypto.SendPepperLogin(ref this.PepperInit, Decrypted);
                            }
                        }
                        else
                        {
                            Encrypted = PepperCrypto.SendPepperAuthentification(ref this.PepperInit, Decrypted);
                        }
                    }

                    Message.Stream.SetByteArray(Encrypted);

                    NetworkTcp.Send(Message.ToBytes, this.Device.Token);
                }
                else
                {
                    Logging.Warning(this.GetType(), "ClientToServer != false at SendMessage(Message " + Message.Type + ").");
                }
            }
            // else
            {
                // Logging.Warning(this.GetType(), "[" + this.Device.BotId + "] IsConnected != true at SendMessage(Message " + Message.Type + ").");
            }
        }
        /// <summary>
        /// Sends the specified message.
        /// </summary>
        /// <param name="Message">The message.</param>
        public void SendMessage(Message Message)
        {
            Logging.Info(typeof(NetworkTcp), "Sending " + Message.GetType().Name + ".");

            if (this.Device.Token.IsConnected)
            {
                if (Message.IsServerToClientMessage)
                {
                    Message.Encode();

                    byte[] Bytes = Message.Stream.ToArray();

                    if (this.SendEncrypter == null)
                    {
                        if (this.PepperInit.State > 0)
                        {
                            if (this.PepperInit.State == 1)
                            {
                                Bytes = PepperCrypto.SendPepperAuthentificationResponse(ref this.PepperInit, Bytes);
                            }
                            else
                            {
                                if (this.PepperInit.State == 3)
                                {
                                    Bytes = PepperCrypto.SendPepperLoginResponse(ref this.PepperInit, out this.SendEncrypter, out this.ReceiveEncrypter, Bytes);
                                }
                            }
                        }
                    }
                    else
                    {
                        Bytes = this.SendEncrypter.Encrypt(Bytes);
                    }

                    Message.Stream.SetByteArray(Bytes);

                    NetworkTcp.Send(this.WriteHeader(Message), this.Device.Token);
                    HandlerFactory.MessageHandle(this.Device, Message); // TODO : Probably call Task.Wait().
                }
                else
                {
                    Logging.Error(this.GetType(), "Message.IsServerToClientMessage != true at SendMessage(Message " + Message.Type + ").");
                }
            }
        }
Exemple #14
0
        /// <summary>
        /// Sends the specified message.
        /// </summary>
        /// <param name="Message">The message.</param>
        public void SendMessage(Message Message)
        {
            Logging.Info(typeof(NetworkTcp), "Sending " + Message.GetType().Name + " to " + this.Device.Token.Socket.RemoteEndPoint + ".");

            if (this.Device.Token.IsConnected)
            {
                // Message.Encode();

                byte[] Bytes = Message.Stream.ToArray();

                if (this.SendEncrypter == null)
                {
                    if (this.PepperInit.State > 0)
                    {
                        if (this.PepperInit.State == 1)
                        {
                            Bytes = PepperCrypto.SendPepperAuthentificationResponse(ref this.PepperInit, Bytes);
                        }
                        else
                        {
                            if (this.PepperInit.State == 3)
                            {
                                Bytes = PepperCrypto.SendPepperLoginResponse(ref this.PepperInit, out this.SendEncrypter, out this.ReceiveEncrypter, Bytes);
                            }
                        }
                    }
                }
                else
                {
                    Bytes = this.SendEncrypter.Encrypt(Bytes);
                }

                Message.Stream.SetByteArray(Bytes);

                Logging.Info(this.GetType(), BitConverter.ToString(Message.ToBytes));

                NetworkTcp.Send(Message.ToBytes, this.Device.Token);
                HandlerFactory.MessageHandle(this.Device, Message).Wait();
            }
        }
        /// <summary>
        /// Sends the specified message.
        /// </summary>
        /// <param name="Buffer">The buffer.</param>
        /// <param name="Token">The token.</param>
        public static void Send(byte[] Buffer, NetworkToken Token)
        {
            if (Buffer == null)
            {
                throw new ArgumentNullException(nameof(Message), "Buffer == null at Send(Buffer, Token).");
            }

            if (Token == null)
            {
                throw new ArgumentNullException(nameof(Token), "Token == null at Send(Buffer, Token).");
            }

            if (Token.IsConnected)
            {
                SocketAsyncEventArgs WriteEvent = NetworkTcp.WritePool.Dequeue();

                if (WriteEvent == null)
                {
                    WriteEvent = new SocketAsyncEventArgs
                    {
                        DisconnectReuseSocket = false
                    };
                }

                WriteEvent.SetBuffer(Buffer, 0, Buffer.Length);

                WriteEvent.AcceptSocket   = Token.Socket;
                WriteEvent.RemoteEndPoint = Token.Socket.RemoteEndPoint;
                WriteEvent.UserToken      = Token;

                if (!Token.Socket.SendAsync(WriteEvent))
                {
                    NetworkTcp.ProcessSend(WriteEvent);
                }
            }
            else
            {
                NetworkTcp.Disconnect(Token.AsyncEvent);
            }
        }
        /// <summary>
        /// Receives the message.
        /// </summary>
        public void ReceiveMessage(short Type, short Version, byte[] Packet)
        {
            if (this.ReceiveEncrypter == null)
            {
                if (this.PepperInit.State == 0)
                {
                    if (Type == 10101)
                    {
                        this.SendEncrypter    = new Rc4Encrypter("fhsd6f86f67rt8fw78fw789we78r9789wer6re", "nonce");
                        this.ReceiveEncrypter = new Rc4Encrypter("fhsd6f86f67rt8fw78fw789we78r9789wer6re", "nonce");

                        Packet = this.ReceiveEncrypter.Decrypt(Packet);
                    }
                    else if (Type == 10100)
                    {
                        Packet = PepperCrypto.HandlePepperAuthentification(ref this.PepperInit, Packet);
                    }
                    else
                    {
                        Packet = null;
                    }
                }
                else
                {
                    if (this.PepperInit.State == 2)
                    {
                        Packet = Type == 10101 ? PepperCrypto.HandlePepperLogin(ref this.PepperInit, Packet) : null;
                    }
                    else
                    {
                        Packet = null;
                    }
                }
            }
            else
            {
                Packet = this.ReceiveEncrypter.Decrypt(Packet);
            }

            if (Packet != null)
            {
                if (this.Device.State != State.Logged)
                {
                    if (Type != 10100 && Type != 10101)
                    {
                        if (++this.InvalidMessageStateCnt >= 5)
                        {
                            NetworkTcp.Disconnect(this.Device.Token.AsyncEvent);
                        }

                        return;
                    }
                }

                using (ByteStream Stream = new ByteStream(Packet))
                {
                    Message Message = MessageFactory.CreateMessage(Type, Stream);

                    if (Message != null)
                    {
                        Logging.Info(this.GetType(), "Receiving " + Message.GetType().Name + ".");

                        if (this.RequestTime.CanHandleMessage(Message))
                        {
                            try
                            {
                                Message.Decode();
                            }
                            catch (Exception Exception)
                            {
                                Logging.Error(this.GetType(), "ReceiveMessage() - An error has been throwed when the message type " + Message.Type + " has been processed. " + Exception);
                            }

                            HandlerFactory.MessageHandle(this.Device, Message); // TODO : Probably call Task.Wait().
                        }
                    }
                    else
                    {
                        Logging.Info(this.GetType(), BitConverter.ToString(Stream.ReadBytes(Stream.BytesLeft)));
                    }
                }
            }
            else
            {
                if (this.Device.State == State.Logged)
                {
                    Logging.Error(this.GetType(), "Packet == null at ReceiveMessage().");
                }
            }
        }