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()); }
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); }
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)); }
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); }
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(); } }
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); }
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()); }
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()); }
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); }