void SendRCONPacket(RCONPacket p) { byte[] Packet = p.OutputAsBytes(); try { rconSocket.BeginSend(Packet, 0, Packet.Length, SocketFlags.None, new AsyncCallback(SendCallback), this); } catch (SocketException se) { OnError(MessageCode.ConnectionClosed, se.Message); Disconnect(); } }
void ProcessIncomingData(PacketState state) { if (state.IsPacketLength) { // First 4 bytes of a new packet. state.PacketLength = BitConverter.ToInt32(state.Data, 0); state.IsPacketLength = false; state.BytesSoFar = 0; state.Data = new byte[state.PacketLength]; if (state.PacketLength > 0) { StartToReceive(state); } else { OnError(MessageCode.EmptyPacket, null); // Treat as a fatal error? Disconnect(); } } else { // This is a fragment of a complete packet. if (state.BytesSoFar < state.PacketLength) { // We don't have all the data, ask the network for the rest. StartToReceive(state); } else { // This is the whole packet, so we can go ahead and pack it up into a structure and then punt it upstairs. #if DEBUG Console.WriteLine("Complete packet."); #endif RCONPacket ReturnedPacket = new RCONPacket(); ReturnedPacket.ParseFromBytes(state.Data, this); ThreadPool.QueueUserWorkItem((object pool_state) => { ProcessResponse(ReturnedPacket); }); // Wait for new packet. GetNewPacketFromServer(); } } }
/// <summary> /// Sends a command to the server. Result is returned asynchronously via callbacks /// so wire those up before using this. /// </summary> /// <param name="command">Command to send.</param> public void ServerCommand(string command) { if (connected) { RCONPacket PacketToSend = new RCONPacket(); ++RequestIDCounter; PacketToSend.RequestId = RequestIDCounter; PacketToSend.ServerDataSent = RCONPacket.SERVERDATA_sent.SERVERDATA_EXECCOMMAND; PacketToSend.String1 = command; SendRCONPacket(PacketToSend); } else { OnError(MessageCode.SendCommandsWhenConnected, null); } }
/// <summary> /// Attempts to connect to server. /// </summary> /// <param name="Server">The IPEndpoint of the server to contact.</param> /// <param name="password">RCON password.</param> public void Connect(IPEndPoint Server, string password) { if (Disposed) { OnError(MessageCode.ConnectionFailed, "Already disposed"); return; } if (disconnected) { OnError(MessageCode.ConnectionFailed, "Previously disconnected"); return; } try { rconSocket.Connect(Server); } catch (SocketException) { OnError(MessageCode.ConnectionFailed, null); OnConnectionSuccess(false); return; } Reset(); RCONPacket ServerAuthPacket = new RCONPacket(); ++RequestIDCounter; ServerAuthPacket.RequestId = RequestIDCounter; ServerAuthPacket.String1 = password; ServerAuthPacket.ServerDataSent = RCONPacket.SERVERDATA_sent.SERVERDATA_AUTH; SendRCONPacket(ServerAuthPacket); //Start the listening loop, now that we've sent auth packet, we should be expecting a reply. GetNewPacketFromServer(); }
void ProcessResponse(RCONPacket P) { switch (P.ServerDataReceived) { case RCONPacket.SERVERDATA_rec.SERVERDATA_AUTH_RESPONSE: if (P.RequestId != -1) { // Connected. connected = true; OnError(MessageCode.ConnectionSuccess, null); OnConnectionSuccess(true); } else { // Failed! OnError(MessageCode.ConnectionFailed, null); OnConnectionSuccess(false); } break; case RCONPacket.SERVERDATA_rec.SERVERDATA_RESPONSE_VALUE: if (hadjunkpacket) { // Real packet! OnServerOutput(MessageCode.ConsoleOutput, P.String1); } else { hadjunkpacket = true; OnError(MessageCode.JunkPacket, null); } break; default: OnError(MessageCode.UnknownResponse, null); break; } }