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