Okay, I spent a few minutes and whipped up a sample RCON client
implementation. This is ugly, ugly code but it should compile for linux
users. Win32 people need to do the WSAStartup() dance amongst other
things. 

In response to an auth request I see:
Sending packet (18 bytes)
Got 28 bytes from server
packet size: 10, request id:0, command:0
packet size: 10, request id:1, command:2

Note that the first packet is a SERVERDATA_RESPONSE_VALUE packet which
you should parse two null strings from. The second packet is a success
response to the auth request (with 2 null strings again). Your program
needs to be able to parse the SERVERDATA_RESPONSE_VALUE and
SERVERDATA_AUTH_RESPONSE responses at any time. The reason for the first
packet is that the rcon server redirects console output (i.e responses
to commands) when any rcon command is run (so you can see the result),
and an auth requests is just another command to the server.






------------------------------------------------------------------------
----------------------------------------------


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <netinet/tcp.h>

int main(int argc, char *argv[] )
{
        int sock = socket(  AF_INET, SOCK_STREAM, IPPROTO_TCP );
        if ( sock == -1 )
        {
                printf( "Socket creation failed" );
                exit(-1);
        }
        
        struct sockaddr_in rcon_server;
        rcon_server.sin_family = AF_INET;
        rcon_server.sin_addr.s_addr = inet_addr( "127.0.0.1" );
        rcon_server.sin_port = htons( 27015 );

        if ( connect( sock, (const struct sockaddr *)&rcon_server,
sizeof( rcon_server ) )!= 0 )
        {
                printf( "Unable to connect\n");
                exit(-1);
        }

        unsigned char send_buf[4096];
        unsigned char *send_ptr = send_buf + sizeof(int);

        *(int *)send_ptr = 0x0001; // request id 1 
        send_ptr += sizeof(int);
        *(int *)send_ptr = 0x0003; // command id 3
        send_ptr += sizeof(int);
        
        strcpy( (char *)send_ptr, "password" ); // the rcon password
        send_ptr += strlen("password") +1; //+1 for null terminator
        *(int *)send_ptr = 0; // 2nd string is just null
        send_ptr++;
        (*(int *)send_buf) = (int)(send_ptr - send_buf - sizeof(int));
// now setup the size of this packet (NOTE the subtraction of
sizeof(int)!!)

        printf( "Sending packet (%d bytes)\n", *(int *)(send_buf) );

        send( sock, send_buf, *(int *)(send_buf) + sizeof(int), 0 ); //
send the auth request

        sleep(1); // ugly hack to give the server time to respond

        long readLen;
        ioctl( sock, FIONREAD, &readLen );
        printf("Got %d bytes from server\n", readLen );

        int len = recv( sock, send_buf, readLen, 0);
        if ( len < 14 )
        {
                printf("Didn't read enough data (%i)( TODO: block on
reads)\n", len);
                exit(-1);
        }

        printf( "packet size: %d, request id:%d, command:%d\n",
                (int)send_buf[0],(int)send_buf[4],(int)send_buf[8]);

        if ( len > 14 ) // a 2nd packet is in the response
        {
                printf( "packet size: %d, request id:%d, command:%d\n",
        
(int)send_buf[14],(int)send_buf[18],(int)send_buf[22]);
        }

        close( sock );
}

------------------------------------------------------------------------
----------------------------------------------

_______________________________________________
hlds_apps mailing list
[EMAIL PROTECTED]
http://list.valvesoftware.com/mailman/listinfo/hlds_apps

Reply via email to