示例#1
0
        public async Task Connect(string address, int port, string password)
        {
            Address  = address;
            Port     = port;
            Password = password;

            if (socket != null)
            {
                throw new Exception("Can't connect on already open socket!");
            }

            log.Info(string.Format("Connect(): Address: {0}, Port: {1}", Address, Port));

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            await Task.Run(() => socket.Connect(Address, Port));

            //socket.Conn)
            // TODO: Change to "TcpClient"?

            networkStream = new NetworkStream(socket);
            streamReader  = new StreamReader(networkStream, Encoding.ASCII);
            streamWriter  = new StreamWriter(networkStream, Encoding.ASCII);
            CommandQueue  = new Queue <RconQueueItem>();
            CurrentState  = RconState.Login;
            _connected    = true;
            log.Info("Connect(): Connected!");

            Task.Run(() => ReadLoop());
            Task.Run(() => WriteLoop());
        }
示例#2
0
        private async void WriteLoop()
        {
            log.Trace("WriteLoop(): Start. Interval: " + SendDelayMs + " ms");
            while (true)
            {
                await Task.Delay(SendDelayMs);

                if (!_connected)
                {
                    break;
                }

                //// If a command uses too long to return we move on
                //if (CurrentState != RconState.Ready)
                //{
                //    if (DateTime.Now > CurrentStateTimeout)
                //        CurrentState = RconState.Ready;
                //}

                if (CurrentState == RconState.Ready)
                {
                    lock (CommandQueue)
                    {
                        if (CommandQueue.Count > 0)
                        {
                            var cmd = CommandQueue.Dequeue();
                            CurrentCommand = cmd;
                            CurrentState   = cmd.PutsInState;
                            CurrentStateWaitingForFirst = true;
                            //CurrentStateTimeout = DateTime.Now.AddMilliseconds(DefaultCommandTimeoutMs);
                            log.Trace("WriteLoop(): Sending command: \"" + cmd.Command + "\"");
                            Write(cmd.Command + "\n" + "\x002" + _doneCommand + "\n");
                        }
                    }
                }
            }
            log.Trace("WriteLoop(): End");
        }
示例#3
0
        private void ProcessLine(string line)
        {
            if (line == null)
            {
                return;
            }

            if (DebugProtocolData)
            {
                log.Trace("ProcessLine(): " + line);
            }

            OnReceivedLine(line);

            // Command completed?
            bool currentStateDone = line.Contains("unknown command: '" + _doneCommand + "'");

            switch (CurrentState)
            {
                #region Login/Auth
            case RconState.Login:
                var greet = reg_Greet.Match(line);
                if (greet.Success)
                {
                    ServerVersion = greet.Groups[1].Value;
                    log.Debug("ProcessLine(): Server version: " + ServerVersion);
                }
                var seed = reg_Seed.Match(line);
                if (seed.Success)
                {
                    CurrentState = RconState.Auth;
                    var ret = "login " + HashString(seed.Groups[1].Value + Password);
                    log.Trace("ProcessLine(): Sending login info: " + ret);
                    Write(ret + "\n");
                    return;
                }
                break;

            case RconState.Auth:
                if (line.StartsWith("Authentication failed"))
                {
                    log.Error("Authentication failed!");
                    CurrentState = RconState.Unknown;
                    OnAuthFailed();
                    Disconnect();
                    return;
                }
                if (line.StartsWith("Authentication successful"))
                {
                    log.Debug("ProcessLine(): Authentication successful. We are logged in.");
                    CurrentState = RconState.Ready;
                    OnConnected();
                    // Start polling
                    StartPollingTimers();
                    return;
                }
                break;

                #endregion
            case RconState.AsyncCommand:
                if (CurrentCommand == null)
                {
                    break;
                }
                if (CurrentStateWaitingForFirst)
                {
                    CurrentStateWaitingForFirst = false;
                    _asyncCommandReturnBuffer   = new List <string>();
                }
                if (currentStateDone)
                {
                    var cc = CurrentCommand;
                    CurrentCommand = null;
                    // Special state - we need to free up for next command, return data to async waiting and completely exit (so we don't re-set CurrentState when new command has started)
                    CurrentState = RconState.Ready;
                    cc.TaskCompletionSource.SetResult(_asyncCommandReturnBuffer);
                    return;
                }
                _asyncCommandReturnBuffer.Add(line);
                break;

            default:
                log.Trace("ProcessLine(): Unhandled line: " + line);
                OnReceivedUnhandledLine(line);
                break;
            }


            if (currentStateDone)
            {
                CurrentState = RconState.Ready;
            }
        }
示例#4
0
        private void ProcessLine(string line)
        {
            if (line == null)
                return;

            if (DebugProtocolData)
                log.Trace("ProcessLine(): " + line);

            OnReceivedLine(line);

            // Command completed?
            bool currentStateDone = line.Contains("unknown command: '" + _doneCommand + "'");

            switch (CurrentState)
            {
                #region Login/Auth
                case RconState.Login:
                    var greet = reg_Greet.Match(line);
                    if (greet.Success)
                    {
                        ServerVersion = greet.Groups[1].Value;
                        log.Debug("ProcessLine(): Server version: " + ServerVersion);
                    }
                    var seed = reg_Seed.Match(line);
                    if (seed.Success)
                    {
                        CurrentState = RconState.Auth;
                        var ret = "login " + HashString(seed.Groups[1].Value + Password);
                        log.Trace("ProcessLine(): Sending login info: " + ret);
                        Write(ret + "\n");
                        return;
                    }
                    break;
                case RconState.Auth:
                    if (line.StartsWith("Authentication failed"))
                    {
                        log.Error("Authentication failed!");
                        CurrentState = RconState.Unknown;
                        OnAuthFailed();
                        Disconnect();
                        return;
                    }
                    if (line.StartsWith("Authentication successful"))
                    {
                        log.Debug("ProcessLine(): Authentication successful. We are logged in.");
                        CurrentState = RconState.Ready;
                        OnConnected();
                        // Start polling
                        StartPollingTimers();
                        return;
                    }
                    break;
                #endregion
                case RconState.AsyncCommand:
                    if (CurrentCommand == null)
                        break;
                    if (CurrentStateWaitingForFirst)
                    {
                        CurrentStateWaitingForFirst = false;
                        _asyncCommandReturnBuffer = new List<string>();
                    }
                    if (currentStateDone)
                    {
                        var cc = CurrentCommand;
                        CurrentCommand = null;
                        // Special state - we need to free up for next command, return data to async waiting and completely exit (so we don't re-set CurrentState when new command has started)
                        CurrentState = RconState.Ready;
                        cc.TaskCompletionSource.SetResult(_asyncCommandReturnBuffer);
                        return;
                    }
                    _asyncCommandReturnBuffer.Add(line);
                    break;

                default:
                    log.Trace("ProcessLine(): Unhandled line: " + line);
                    OnReceivedUnhandledLine(line);
                    break;

            }


            if (currentStateDone)
                CurrentState = RconState.Ready;

        }
示例#5
0
        private async void WriteLoop()
        {
            log.Trace("WriteLoop(): Start. Interval: " + SendDelayMs + " ms");
            while (true)
            {
                await Task.Delay(SendDelayMs);
                if (!_connected)
                    break;

                //// If a command uses too long to return we move on
                //if (CurrentState != RconState.Ready)
                //{
                //    if (DateTime.Now > CurrentStateTimeout)
                //        CurrentState = RconState.Ready;
                //}

                if (CurrentState == RconState.Ready)
                {
                    lock (CommandQueue)
                    {

                        if (CommandQueue.Count > 0)
                        {
                            var cmd = CommandQueue.Dequeue();
                            CurrentCommand = cmd;
                            CurrentState = cmd.PutsInState;
                            CurrentStateWaitingForFirst = true;
                            //CurrentStateTimeout = DateTime.Now.AddMilliseconds(DefaultCommandTimeoutMs);
                            log.Trace("WriteLoop(): Sending command: \"" + cmd.Command + "\"");
                            Write(cmd.Command + "\n" + "\x002" + _doneCommand + "\n");
                        }
                    }
                }
            }
            log.Trace("WriteLoop(): End");
        }
示例#6
0
        public async Task Connect(string address, int port, string password)
        {
            Address = address;
            Port = port;
            Password = password;

            if (socket != null)
                throw new Exception("Can't connect on already open socket!");

            log.Info(string.Format("Connect(): Address: {0}, Port: {1}", Address, Port));

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            await Task.Run(() => socket.Connect(Address, Port));
            //socket.Conn)
            // TODO: Change to "TcpClient"?

            networkStream = new NetworkStream(socket);
            streamReader = new StreamReader(networkStream, Encoding.ASCII);
            streamWriter = new StreamWriter(networkStream, Encoding.ASCII);
            CommandQueue = new Queue<RconQueueItem>();
            CurrentState = RconState.Login;
            _connected = true;
            log.Info("Connect(): Connected!");

            Task.Run(() => ReadLoop());
            Task.Run(() => WriteLoop());
        }