Пример #1
0
        private static void DoHandleClient(object objClient)
        {
            currentClient = (RCONClient)objClient;
            if (ValidRCONClients.Count == 0)
            {
                currentClient.SetLoginState(RCONClient.ELoginState.LoggedIn);
            }

            try
            {
                HandleClient();
            }
            catch (Exception e)
            {
                LogManager.Error("RCON", "Exception occured in RCON thread for " + currentClient.RemoteEndpoint);
                LogManager.Error("RCON", e.ToString());
            }

            if (currentClient.tcpClient.Connected)
            {
                currentClient.tcpClient.Close();
            }
        }
Пример #2
0
        private static void HandleClient()
        {
            LogManager.Log("RCON", "Accepted RCON connection from " + currentClient.Username + " (" + currentClient.RemoteEndpoint + ")");

            bool          closingConnection = false;
            NetworkStream stream            = currentClient.tcpClient.GetStream();

            string welcomeString = Program.BismuthWelcomeHeader + "\r\nWelcome to this Bismuth RCON server\r\n";

            if (true) //Check if login required
            {
                welcomeString += "\r\n" + UsernamePrompt;
            }

            SendClientResponse(stream, Encoding.ASCII.GetBytes(welcomeString));

            Stopwatch timeSinceLastRequest = new Stopwatch();
            Stopwatch timeSinceLastInput   = new Stopwatch();

            while (!closingConnection)
            {
                timeSinceLastRequest.Restart();

                LinkedList <byte> requestData = new LinkedList <byte>();
                byte lastByte = 255;
                while (lastByte != 10)
                {
                    timeSinceLastInput.Restart();

                    while (currentClient.tcpClient.Available == 0)
                    {
                        Thread.Sleep(2);
                        if (timeSinceLastRequest.ElapsedMilliseconds > RCONConnectionMaxTTL * 1000)
                        {
                            SendClientResponse(stream, ttlFullExpiredText, true);
                            closingConnection = true;
                            break;
                        }
                        else if (timeSinceLastInput.ElapsedMilliseconds > RCONConnectionInputTTL * 1000)
                        {
                            SendClientResponse(stream, ttlInputExpiredText, true);
                            closingConnection = true;
                            break;
                        }
                    }

                    if (!currentClient.tcpClient.Connected || closingConnection)
                    {
                        closingConnection = true;
                        break;
                    }

                    byte[] pdata = new byte[currentClient.tcpClient.Available];
                    stream.Read(pdata, 0, pdata.Length);
                    for (int i = 0; i < pdata.Length; i++)
                    {
                        if (pdata[i] == 8) //Backspace
                        {
                            if (requestData.Count > 0)
                            {
                                requestData.RemoveLast();
                            }

                            continue;
                        }

                        requestData.AddLast(pdata[i]);
                    }

                    lastByte = requestData.Last == null ? lastByte: requestData.Last.Value;
                }

                if (closingConnection || !currentClient.tcpClient.Connected)
                {
                    break;
                }

                string requestString = Encoding.ASCII.GetString(requestData.ToArray()).TrimEnd('\r', '\n');
                requestString = new string(requestString.Where(c => !char.IsControl(c)).ToArray());

                if (requestString == "" && currentClient.LoginState == RCONClient.ELoginState.NotLoggedIn)
                {
                    requestString = "quit";
                    currentClient.SetLoginState(RCONClient.ELoginState.LoggedIn); //Will be booted straight out again
                }

                if (currentClient.LoginState == RCONClient.ELoginState.NotLoggedIn)
                {
                    currentClient.SetUsername(requestString);
                    currentClient.SetLoginState(RCONClient.ELoginState.NeedPassword);
                    SendClientResponse(stream, PasswordPrompt);
                }
                else if (currentClient.LoginState == RCONClient.ELoginState.NeedPassword)
                {
                    if ((ValidRCONClients.ContainsKey(currentClient.Username) || ValidRCONClients.ContainsKey("@" + currentClient.Username)) &&
                        AuthManager.CheckPlaintextCredentials(authType, requestString, ValidRCONClients[currentClient.Username]))
                    {
                        SendClientResponse(stream, LoginSuccessfulText + currentClient.Username + "!\r\n");
                        currentClient.SetLoginState(RCONClient.ELoginState.LoggedIn);
                        LogManager.Log("RCON", "Client " + currentClient.Username + " successfully logged in");
                    }
                    else
                    {
                        LogManager.Log("RCON", "Client " + currentClient.RemoteEndpoint + " failed to login as " + currentClient.Username);
                        currentClient.SetUsername(currentClient.RemoteEndpoint);
                        SendClientResponse(stream, LoginFailedText);
                        currentClient.SetLoginState(RCONClient.ELoginState.NotLoggedIn);
                    }
                }
                else if (currentClient.LoginState == RCONClient.ELoginState.LoggedIn)
                {
                    string[] request = requestString.Split(' ');

                    if (request.Length == 0)
                    {
                        continue;
                    }

                    string   command     = request[0].ToLower();
                    string[] commandArgs = request.Skip(1).ToArray();

                    if (command == "quit" || command == "disconnect" || command == "exit")
                    {
                        command           = "quit";
                        closingConnection = true;
                    }

                    byte[] responseData;
                    if (commands.ContainsKey(command))
                    {
                        object response = commands[command].Invoke(commandArgs);
                        if (response is byte[])
                        {
                            responseData = (byte[])response;
                        }
                        else
                        {
                            responseData = Encoding.ASCII.GetBytes(response.ToString());
                        }
                    }
                    else
                    {
                        //Presume that the request contained secure data
                        LogManager.Log("RCON - " + currentClient.Username + TelnetInputPromptStr + command + " + " + commandArgs.Length + " args");
                        responseData = Encoding.ASCII.GetBytes("Error: Unknown command '" + command + "'");
                    }

                    SendClientResponse(stream, responseData, closingConnection);
                }
            }

            LogManager.Log("RCON", "Closed RCON connection from " + currentClient.Username + " (" + currentClient.RemoteEndpoint + ")");
            currentClient.tcpClient.Close();
        }
Пример #3
0
        private static void DoHandleClient(object objClient)
        {
            currentClient = (RCONClient)objClient;
            if (ValidRCONClients.Count == 0)
                currentClient.SetLoginState(RCONClient.ELoginState.LoggedIn);

            try
            {
                HandleClient();
            }
            catch (Exception e)
            {
                LogManager.Error("RCON", "Exception occured in RCON thread for " + currentClient.RemoteEndpoint);
                LogManager.Error("RCON", e.ToString());
            }

            if (currentClient.tcpClient.Connected)
                currentClient.tcpClient.Close();
        }