/// <summary> /// Sends a command to the RCON server /// </summary> /// <returns>A task with the response packet</returns> public async Task <RCONPacket> SendCommandAsync(string command, RCONPacketType type = RCONPacketType.ExecCommand) { RCONPacket packet = new RCONPacket(GenerateID(), type, command); var task = new TaskCompletionSource <RCONPacket>(); pendingPackets.Add(packet.Id, task); await this.socket.SendAsync(packet.ToBytes(), SocketFlags.None); return(await task.Task); }
/// <summary> /// Converts a buffer to a packet. /// </summary> /// <param name="buffer">Buffer to read.</param> /// <returns>Created packet.</returns> internal static RCONPacket FromBytes(byte[] buffer) { if (buffer == null) { throw new NullReferenceException("Byte buffer cannot be null."); } if (buffer.Length < 4) { throw new InvalidDataException("Buffer does not contain a size field."); } if (buffer.Length > MAX_PACKET_SIZE) { throw new InvalidDataException("Buffer is too large for an RCON packet."); } int size = BitConverter.ToInt32(buffer, 0); if (size > buffer.Length - 4) { throw new InvalidDataException("Packet size specified was larger then buffer"); } if (size < 10) { throw new InvalidDataException("Packet received was invalid."); } int id = BitConverter.ToInt32(buffer, 4); RCONPacketType type = (RCONPacketType)BitConverter.ToInt32(buffer, 8); try { // Force string to \r\n line endings char[] rawBody = Encoding.UTF8.GetChars(buffer, 12, size - 10); string body = new string(rawBody, 0, size - 10).TrimEnd(); body = Regex.Replace(body, @"\r\n|\n\r|\n|\r", "\r\n"); return(new RCONPacket(id, type, body)); } catch (Exception ex) { Console.Error.WriteLine($"{DateTime.Now} - Error reading RCON packet from server: " + ex.Message); return(new RCONPacket(id, type, "")); } }
public static RCONPacket ReadData(byte[] data) { // Skip length header (4 bytes) data = data.Skip(4).ToArray(); // Grab packet ID (4 bytes) int packetID = BitConverter.ToInt32(data.Take(4).ToArray(), 0); data = data.Skip(4).ToArray(); // Grab packet type (4 bytes) RCONPacketType packetType = (RCONPacketType)BitConverter.ToInt32(data.Take(4).ToArray(), 0); data = data.Skip(4).ToArray(); // Get body, remove last two bytes (string terminator) data = data.Take(data.Length - 2).ToArray(); string packetBody = Encoding.UTF8.GetString(data); if (packetType == RCONPacketType.AUTH_RESPONSE) { return(new RCONAuthResponsePacket() { ID = packetID, Type = packetType, Body = packetBody }); } return(new RCONPacket() { ID = packetID, Type = packetType, Body = packetBody }); }
/// <summary> /// Create a new packet. /// </summary> /// <param name="id">Some kind of identifier to keep track of responses from the server.</param> /// <param name="type">What the server is supposed to do with the body of this packet.</param> /// <param name="body">The actual information held within.</param> public RCONPacket(int id, RCONPacketType type, string body) { this.Id = id; this.Type = type; this.Body = body; }