예제 #1
0
        private string sendCommand(string command, bool isMultipacketResponse)
        {
            RconSrcPacket senPacket = new RconSrcPacket()
            {
                Body = command, Id = (int)PacketId.ExecCmd, Type = (int)PacketType.Exec
            };
            List <byte[]> recvData = socket.GetMultiPacketResponse(RconUtil.GetBytes(senPacket));
            StringBuilder str      = new StringBuilder();

            try
            {
                for (int i = 0; i < recvData.Count; i++)
                {
                    //consecutive rcon command replies start with an empty packet
                    if (BitConverter.ToInt32(recvData[i], 4) == (int)PacketId.Empty)
                    {
                        continue;
                    }
                    if (recvData[i].Length - BitConverter.ToInt32(recvData[i], 0) == 4)
                    {
                        str.Append(RconUtil.ProcessPacket(recvData[i]).Body);
                    }
                    else
                    {
                        str.Append(RconUtil.ProcessPacket(recvData[i]).Body + Util.BytesToString(recvData[++i].Take(recvData[i].Length - 2).ToArray()));
                    }
                }
            }
            catch (Exception e)
            {
                e.Data.Add("ReceivedData", recvData.SelectMany(x => x).ToArray());
                throw;
            }
            return(str.ToString());
        }
예제 #2
0
        internal static RconSrcPacket ProcessPacket(byte[] data)
        {
            var packet = new RconSrcPacket();

            try
            {
                var parser = new Parser(data);
                packet.Size = parser.ReadInt();
                packet.Id   = parser.ReadInt();
                packet.Type = parser.ReadInt();
                var body = parser.GetUnParsedBytes();
                if (body.Length == 2)
                {
                    packet.Body = string.Empty;
                }
                else
                {
                    packet.Body = Util.BytesToString(body, 0, body.Length - 3);
                }
            }
            catch (Exception e)
            {
                e.Data.Add("ReceivedData", data == null ? new byte[1] : data);
                throw;
            }
            return(packet);
        }
예제 #3
0
 internal static Rcon Authorize(ConnectionInfo conInfo, string msg)
 {
     return(new QueryMasterBase().Invoke <Rcon>(() =>
     {
         RconSource obj = new RconSource(conInfo);
         obj.socket = new TcpQuery(conInfo);
         byte[] recvData = new byte[50];
         RconSrcPacket packet = new RconSrcPacket()
         {
             Body = msg, Id = (int)PacketId.ExecCmd, Type = (int)PacketType.Auth
         };
         recvData = obj.socket.GetResponse(RconUtil.GetBytes(packet));
         int header;
         try
         {
             header = BitConverter.ToInt32(recvData, 4);
         }
         catch (Exception e)
         {
             e.Data.Add("ReceivedData", recvData == null ? new byte[1] : recvData);
             throw;
         }
         if (header != -1)
         {
             return obj;
         }
         return obj;
     }, conInfo.Retries + 1, null, conInfo.ThrowExceptions));
 }
예제 #4
0
        private async Task <string> sendCommandAsync(string command)
        {
            var send = new RconSrcPacket()
            {
                Body = command, Id = (int)PacketId.ExecCmd, Type = (int)PacketType.Exec
            };
            Exception lastException = null;

            try
            {
                var result = await _socket.GetResponseAsync(send);

                return(result?.Body);
            }
            catch (Exception ex) { lastException = ex; }

            if (!Reconnect())
            {
                throw new QueryMasterException("Send command and reconnect failed", lastException);
            }

            var resultSecond = await _socket.GetResponseAsync(send);

            return(resultSecond?.Body);
        }
예제 #5
0
        internal async Task <RconSrcPacket> GetResponseAsync(RconSrcPacket senPacket)
        {
            if (_procTask == null)
            {
                throw new QueryMasterException($"{nameof(TcpQuery)} must be initialized before calling {nameof(GetResponseAsync)}");
            }
            if (_procTask.IsCompleted)
            {
                throw new QueryMasterException("Receive thread is in a failed state");
            }

            var tcs     = new TaskCompletionSource <RconSrcPacket>();
            var handler = new OnPacketEventHandler((data, exception) =>
            {
                if (data != null)
                {
                    var packet = RconUtil.ProcessPacket(data);
                    if (packet.Id == senPacket.Id)
                    {
                        tcs.SetResult(packet);
                    }
                }

                if (exception != null)
                {
                    tcs.SetException(exception);
                }
            });

            try
            {
                await _ss.WaitAsync();

                OnPacket += handler;
                try
                {
                    SendData(RconUtil.GetBytes(senPacket));
                }
                catch (Exception ex) { throw new QueryMasterException("Failed to send packet", ex); }

                if (await Task.WhenAny(tcs.Task, Task.Delay(_conInfo.ReceiveTimeout)) == tcs.Task)
                {
                    return(tcs.Task.Result);
                }
                else
                {
                    return(null);
                }
            }
            finally
            {
                OnPacket -= handler;
                _ss.Release();
            }
        }
예제 #6
0
        internal static RconSrcPacket ProcessPacket(byte[] data, bool firstPacket, bool lastPacket)
        {
            RconSrcPacket packet = new RconSrcPacket();

            try
            {
                byte[] body = new byte[] { };

                // Current RCON implementation is not to the specifications
                // Only the first packet has the header information - following packets
                // are just a continuation of the response without any header
                if (firstPacket)
                {
                    Parser parser = new Parser(data);
                    packet.Size = parser.ReadInt();
                    packet.Id   = parser.ReadInt();
                    packet.Type = parser.ReadInt();
                    body        = parser.GetUnParsedBytes();
                }
                else
                {
                    // any packet after the first is just continuation of the response
                    body = data;
                }

                if (body.Length == 2)
                {
                    packet.Body = string.Empty;
                }
                else
                {
                    if (lastPacket)
                    {
                        packet.Body = Util.BytesToString(body, 0, body.Length - 3);
                    }
                    else
                    {
                        packet.Body = Util.BytesToString(body, 0, body.Length);
                    }
                }
                //Console.WriteLine(packet.Body);
                //Console.WriteLine();
            }
            catch (Exception e)
            {
                e.Data.Add("ReceivedData", data == null ? new byte[1] : data);
                throw;
            }
            return(packet);
        }
예제 #7
0
        internal static byte[] GetBytes(RconSrcPacket packet)
        {
            byte[] command = Util.StringToBytes(packet.Body);
            packet.Size = 10 + command.Length;
            List <byte> y = new List <byte>(packet.Size + 4);

            y.AddRange(BitConverter.GetBytes(packet.Size));
            y.AddRange(BitConverter.GetBytes(packet.Id));
            y.AddRange(BitConverter.GetBytes(packet.Type));
            y.AddRange(command);
            //part of string
            y.Add(0x00);
            //end terminater
            y.Add(0x00);
            return(y.ToArray());
        }
예제 #8
0
        private string sendCommand(string command, bool isMultipacketResponse)
        {
            RconSrcPacket senPacket = new RconSrcPacket()
            {
                Body = command, Id = (int)PacketId.ExecCmd, Type = (int)PacketType.Exec
            };
            List <byte[]> recvData    = socket.GetMultiPacketResponse(RconUtil.GetBytes(senPacket));
            StringBuilder str         = new StringBuilder();
            bool          lastPacket  = false;
            bool          firstPacket = false;

            try
            {
                for (int i = 0; i < recvData.Count; i++)
                {
                    if (BitConverter.ToInt32(recvData[i], 4) == (int)PacketId.Empty)
                    {
                        continue;
                    }
                    if (recvData[i].Length - BitConverter.ToInt32(recvData[i], 0) == 4)
                    {
                        str.Append(RconUtil.ProcessPacket(recvData[i]).Body);
                    }
                    else
                    {
                        lastPacket  = (i == recvData.Count - 1);
                        firstPacket = i == 0;
                        str.Append(RconUtil.ProcessPacket(recvData[i], firstPacket, lastPacket).Body);
                    }
                }
            }
            catch (Exception e)
            {
                e.Data.Add("ReceivedData", recvData.SelectMany(x => x).ToArray());
                throw;
            }
            return(str.ToString());
        }
예제 #9
0
        private bool Reconnect()
        {
            if (_socket != null)
            {
                try
                {
                    _socket.Dispose();
                    _socket = null;
                }
                catch { }
            }

            _socket = new TcpQuery(_connInfo);

            //attempt to authorize this conenction
            var packet = new RconSrcPacket()
            {
                Body = _password, Id = (int)PacketId.ExecCmd, Type = (int)PacketType.Auth
            };
            var buffer = _socket.GetResponse(RconUtil.GetBytes(packet));

            if (buffer == null || buffer.Length < 4)
            {
                return(false);
            }

            var header = BitConverter.ToInt32(buffer, 4);

            if (header == -1)
            {
                return(false);
            }

            _socket.Init();
            return(true);
        }