//Private helper methods private void PrivateGetPackets(RconPacket input, GotPacketCallback callback) { //Get ID and incrememnt it int id = currentId++; int testId = currentId++;//This id will be used to check when we're done. input.id = id; //Register a callback for this and the next one. int packetsGot = 0; //How many packets were recievied for a single ID. List <RconPacket> returnedPackets = new List <RconPacket>(); var innerCallback = (new InternalPacketCallback((RconPacket p) => { //When a packet is received, this is called. //A request to the server will be sent using the same ID. When that packet is recieved, we know we are done. This is for getting multiple packets for one request if it is too long. RconPacketType type = (RconPacketType)p.type; bool isEnd = testId == p.id; //Check if the raw contents match the end of packet results if (packetsGot == 0) { //Send a request to check if we are done. sock.Send(new RconPacket(testId, RconPacketType.SERVERDATA_RESPONSE_VALUE, "").ToBytes()); } if (isEnd) { //This is the end. Return all of our packets. callback(returnedPackets); //Also remove this callback from the dictonary to save ram internalCallbacks.Remove(id); internalCallbacks.Remove(testId); } else { //Add this because it's not the ending packet. returnedPackets.Add(p); } packetsGot++; })); internalCallbacks.Add(id, innerCallback); internalCallbacks.Add(testId, innerCallback); //Send packet to the server. byte[] data = input.ToBytes(); //Send sock.Send(data); }
private void PrivateGotPacket(System.IAsyncResult result) { //Check if disposed if (sock == null) { return; } //Get the data out of this. sock.EndReceive(result); pendingAsync = null; //We'll now read in the size of the packet based on the "receiveBuffer" int sent. int size = ReadIntFromStream(receiveBuffer); //We'll now read in the remainder of the packet. byte[] buffer = new byte[size + 4]; //Copy the current receiveBuffer to this buffer. This'll allow us to have the length. receiveBuffer.CopyTo(buffer, 0); //Now, read in the remainder of the packet from the socket. sock.Receive(buffer, 4, size, SocketFlags.None); //We'll now begin listening again. PrivateBeginWaitingForPacket(); //Now, we'll convert this to a real packet we can understand. RconPacket packet = null; try { packet = RconPacket.ToPacket(buffer); //If the callback list contains this, call back. Ignore Ark's "Keep Alive" packets. if (internalCallbacks.ContainsKey(packet.id) && packet.body != "Keep Alive") { internalCallbacks[packet.id](packet); } } catch (Exception ex) { //There was an error. throw ex; } }
public static RconPacket ToPacket(byte[] data) { //Do the opposite as the above. RconPacket packet = new RconPacket(); using (MemoryStream ms = new MemoryStream(data)) { //First, read in the size. int length = ReadIntFromStream(ms); //Read id packet.id = ReadIntFromStream(ms); //Read type packet.type = ReadIntFromStream(ms); //Now, read body. int bodySize = length - 4 - 4 - 2; //Remove last two bytes of padding and the id and type. packet.rawBody = ReadBytesFromStream(ms, bodySize); packet.body = Encoding.ASCII.GetString(packet.rawBody); //Read last two bytes of padding ReadBytesFromStream(ms, 2); } return(packet); }