private RconResponse PrivateSendPacketAndGetResponse(RconPacketType type, string body, int timeoutMs = 900, bool reconnectOnFail = true) { //This is a bit gross. I should find a way around this. //We want to hang the thread while we search for the response. //If it takes too long, respond with a timeout. var task = Task.Run(() => PrivateTaskSendPacketAndGetResponse(type, body, timeoutMs)); if (task.Wait(TimeSpan.FromMilliseconds(timeoutMs))) { return(task.Result); } else { //Timeout. if (reconnectOnFail) { //Try to reconnect. DisposeNetworking(); PrepareNetworking(); Console.WriteLine("Reconnected"); //Resend command return(PrivateSendPacketAndGetResponse(type, body, timeoutMs, false)); } return(RconResponse.CreateBadResponse(RconResponseStatus.Timeout)); } }
public static RconResponse CreatFatalResponse(Exception _ex) { //Used when an item was created with an error. RconResponse rr = new RconResponse(); rr.status = RconResponseStatus.FatalError; rr.ex = _ex; return(rr); }
public static RconResponse CreateBadResponse(RconResponseStatus status) { //Used when an item was created with a problem. RconResponse rr = new RconResponse(); rr.status = status; if (status == RconResponseStatus.Ok) //What!? Wrong function { throw new Exception("Incorrect status! You're creating a bad response, but you've passed an 'Ok' status in. Check the function you're using and try again."); } //Return return(rr); }
public static RconResponse CreateOkayResponse(RconPacketType _type, int _id, byte[] _body) { //Used when a response was correctly downloaded RconResponse rr = new RconResponse(); rr.type = _type; rr.id = _id; rr.body = Encoding.ASCII.GetString(_body); rr.status = RconResponseStatus.Ok; //If the message is "Keep Alive", then set the status. if (rr.body == "Keep Alive") { rr.status = RconResponseStatus.KeepAliveError; } return(rr); }
private async Task <RconResponse> PrivateTaskSendPacketAndGetResponse(RconPacketType type, string body, int timeoutMs) { //Clear ClearMainStream(); //Send PrivateSendPacket(type, body); DateTime start = DateTime.UtcNow; //Save the starting date so we can timeout. while (true) { //Keep trying to read from the stream. try { int responseLength = networkReader.ReadInt32(); //Fetch the packet length. Then, read in. int id = networkReader.ReadInt32(); //Read in the ID of the client that sent this. We should make sure this is ours. RconPacketType responseType = (RconPacketType)networkReader.ReadInt32(); //Fetch packet type //Read bytes in. byte[] buffer = networkReader.ReadBytes(responseLength - 10); //Read the body in. Use the length minus the header length of 10. //Read padding networkReader.Read(); networkReader.Read(); //Create a response. RconResponse response = RconResponse.CreateOkayResponse(responseType, id, buffer); //Return this return(response); } catch (Exception ex) { } //Some other error occured. Try again, but keep checking for a timeout. TimeSpan totalTime = DateTime.UtcNow - start; if (totalTime.TotalMilliseconds > timeoutMs) { //Timeout. Create bad response. return(RconResponse.CreateBadResponse(RconResponseStatus.Timeout)); } } }
public RconResponse SendCommand(string cmd, int timeout = 900) { //Check if we're connected if (status != RconConnectionStatus.Connected) { //Uh oh. Disconnected. //Try to reconnect. PrepareNetworking(); if (status != RconConnectionStatus.Connected) { return(RconResponse.CreateBadResponse(RconResponseStatus.ServerDisconnected)); } //Reconnected! Connect... } //This function places everything in a try except. try { return(PrivateSendPacketAndGetResponse(RconPacketType.SERVERDATA_EXECCOMMAND_OR_SERVERDATA_AUTH_RESPONSE, cmd, timeout)); } catch (Exception ex) { return(RconResponse.CreatFatalResponse(ex)); } }