예제 #1
0
        /// <summary>
        ///     Sends the authentication to the server
        /// </summary>
        /// <param name="password">RCON Password</param>
        public void Authenticate(string password)
        {
            _packetId++;
            var packet = new RemoteConPacket(_packetId, RemoteConPacket.PacketType.Auth, password, UseUTF8);

            SendPacket(packet);
        }
        /// <summary>
        ///     Sends the specified packet to the client
        /// </summary>
        /// <param name="packet">The packet to send</param>
        /// <exception cref="Exception">Not connected</exception>
        private void SendPacket(RemoteConPacket packet)
        {
            if (!_client.Connected)
            {
                throw new Exception("Not connected.");
            }

            var packetBytes = packet.GetBytes();

            //_ns.Write(packetBytes, 0, packetBytes.Length);
            _ns.BeginWrite(packetBytes, 0, packetBytes.Length - 1, ar => { _ns.EndWrite(ar); }, null);
        }
        /// <summary>
        ///     Parses raw bytes to RemoteConPacket
        /// </summary>
        /// <param name="rawPacket"></param>
        internal void ParsePacket(byte[] rawPacket)
        {
            try
            {
                var packet = new RemoteConPacket(rawPacket);
                if (!Authenticated)
                {
                    // ExecCommand is AuthResponse too.
                    if (packet.Type == RemoteConPacket.PacketType.ExecCommand)
                    {
                        if (packet.Id == -1)
                        {
                            Log("Authentication failed.");
                            Authenticated = false;
                            if (OnAuthResult != null)
                            {
                                OnAuthResult(false);
                            }
                        }
                        else
                        {
                            Log("Authentication success.");
                            Authenticated = true;
                            if (OnAuthResult != null)
                            {
                                OnAuthResult(false);
                            }
                        }
                    }

                    return;
                }

                if (_requestedCommands.ContainsKey(packet.Id) &&
                    packet.Type == RemoteConPacket.PacketType.ResponseValue)
                {
                    _requestedCommands[packet.Id](packet.Payload);
                }
                else
                {
                    Log("Got packet with invalid id " + packet.Id);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                Log(e.ToString());
            }
        }
예제 #4
0
        /// <summary>
        ///     Sends the specified packet to the client
        /// </summary>
        /// <param name="packet">The packet to send</param>
        /// <exception cref="Exception">Not connected</exception>
        private void SendPacket(RemoteConPacket packet)
        {
            if (_client == null || !_client.Connected)
            {
                throw new Exception("Not connected.");
            }

            var packetBytes = packet.GetBytes();

            try
            {
                _ns.BeginWrite(packetBytes, 0, packetBytes.Length - 1, ar => { _ns.EndWrite(ar); }, null);
            }
            catch (ObjectDisposedException) { } // Do not write to NetworkStream when it's closed.
            catch (IOException) { }             // Do not write to Socket when it's closed.
        }
예제 #5
0
        /// <summary>
        ///     Sends the specified packet to the client
        /// </summary>
        /// <param name="packet">The packet to send</param>
        /// <exception cref="Exception">Not connected</exception>
        private void SendPacket(RemoteConPacket packet)
        {
            if (_isUnitTest)
            {
                return;
            }

            if (!_connected)
            {
                throw new Exception("Not connected.");
            }

            var ackBytes = packet.GetBytes();

            _ns.Write(ackBytes, 0, ackBytes.Length - 1);
        }
예제 #6
0
        /// <summary>
        ///     Sends a RCON Command to the server
        /// </summary>
        /// <param name="command">The RCON command with parameters</param>
        /// <param name="resultFunc">A function that will be executed after the server has processed the request</param>
        /// <exception cref="NotAuthenticatedException">If we're not authenticated</exception>
        public void SendCommand(string command, CommandResult resultFunc)
        {
            if (!_client.Connected)
            {
                return;
            }

            if (!Authenticated)
            {
                throw new NotAuthenticatedException();
            }

            _packetId++;
            _requestedCommands.Add(_packetId, resultFunc);

            var packet = new RemoteConPacket(_packetId, RemoteConPacket.PacketType.ExecCommand, command, UseUTF8);

            SendPacket(packet);
        }
예제 #7
0
        /// <summary>
        ///     Parses raw bytes to RemoteConPacket
        /// </summary>
        /// <param name="rawPacket"></param>
        internal void ParsePacket(byte[] rawPacket)
        {
            try
            {
                var packet = new RemoteConPacket(rawPacket);

                if (!_isUnitTest)
                {
                    _remoteConServer.LogDebug(((IPEndPoint)_tcp.Client.RemoteEndPoint).Address + " sent packet " +
                                              packet.Type + "!");
                }

                // Do not allow any other packets than auth to be sent when client is not authenticated
                if (!Authenticated)
                {
                    if (packet.Type != RemoteConPacket.PacketType.Auth)
                    {
                        if (_isUnitTest)
                        {
                            throw new NotAuthenticatedException();
                        }
                        CloseConnection();
                    }

                    _authTries++;

                    if (packet.Payload == _remoteConServer.Password)
                    {
                        if (!_isUnitTest)
                        {
                            _remoteConServer.LogDebug(((IPEndPoint)_tcp.Client.RemoteEndPoint).Address +
                                                      " successfully authenticated!");
                        }
                        Authenticated = true;

                        if (!_remoteConServer.SendAuthImmediately)
                        {
                            SendPacket(new RemoteConPacket(packet.Id, RemoteConPacket.PacketType.ResponseValue, ""));
                        }

                        SendPacket(new RemoteConPacket(packet.Id, RemoteConPacket.PacketType.ExecCommand, ""));
                        return;
                    }

                    if (_authTries >= _remoteConServer.MaxPasswordTries)
                    {
                        if (_remoteConServer.BanMinutes > 0)
                        {
                            _remoteConServer.IpBanList.Add(((IPEndPoint)_tcp.Client.RemoteEndPoint).Address.ToString(),
                                                           DateTime.Now.AddMinutes(_remoteConServer.BanMinutes).ToUnixTimestamp());
                        }

                        CloseConnection();
                        return;
                    }

                    if (!_isUnitTest)
                    {
                        _remoteConServer.LogDebug(((IPEndPoint)_tcp.Client.RemoteEndPoint).Address +
                                                  " entered wrong password!");
                    }

                    if (!_remoteConServer.SendAuthImmediately)
                    {
                        SendPacket(new RemoteConPacket(packet.Id, RemoteConPacket.PacketType.ResponseValue, ""));
                    }

                    SendPacket(new RemoteConPacket(-1, RemoteConPacket.PacketType.ExecCommand, ""));

                    return;
                }

                // Invalid packet type.
                if (packet.Type != RemoteConPacket.PacketType.ExecCommand)
                {
                    if (_isUnitTest)
                    {
                        throw new InvalidPacketTypeException();
                    }

                    _remoteConServer.LogDebug(((IPEndPoint)_tcp.Client.RemoteEndPoint).Address +
                                              " sent a packet with invalid type!");

                    if (_remoteConServer.InvalidPacketKick)
                    {
                        CloseConnection();
                    }
                    return;
                }

                if (packet.Payload == "")
                {
                    if (_isUnitTest)
                    {
                        throw new EmptyPacketPayloadException();
                    }
                    _remoteConServer.LogDebug(((IPEndPoint)_tcp.Client.RemoteEndPoint).Address +
                                              " sent a packet with empty payload!");

                    if (_remoteConServer.EmptyPayloadKick)
                    {
                        CloseConnection();
                    }
                    return;
                }

                var args = ArgumentParser.ParseLine(packet.Payload);
                var cmd  = args[0];
                args.RemoveAt(0);

                if (_remoteConServer.UseCustomCommandHandler)
                {
                    var result = _remoteConServer.ExecuteCustomCommandHandler(cmd, args);
                    SendPacket(new RemoteConPacket(packet.Id, RemoteConPacket.PacketType.ResponseValue,
                                                   result));
                    return;
                }

                var command = _remoteConServer.CommandManager.GetCommand(cmd);
                if (command == null)
                {
                    SendPacket(new RemoteConPacket(packet.Id, RemoteConPacket.PacketType.ResponseValue,
                                                   "Invalid command \"" + packet.Payload + "\""));
                }
                else
                {
                    var commandResult = command.Handler(cmd, args);
                    // TODO: Split packets?
                    SendPacket(new RemoteConPacket(packet.Id, RemoteConPacket.PacketType.ResponseValue,
                                                   commandResult));
                }
            }
            catch (RconServerException)
            {
                throw;
            }
            catch (Exception e)
            {
                if (_isUnitTest)
                {
                    throw;
                }

                if (!_isUnitTest)
                {
                    _remoteConServer.LogDebug(string.Format("Client {0} caused an exception: {1} and was killed.",
                                                            ((IPEndPoint)_tcp.Client.RemoteEndPoint).Address, e.Message));
                }

                CloseConnection();
            }
        }