Results 1 to 4 of 4

Thread: Sending server commands to the clients

  1. #1
    Global Mossaderator Mitch's Avatar
    Join Date
    Nov 2012
    Posts
    654
    Thanks
    204
    Thanked 450 Times in 305 Posts

    Sending server commands to the clients

    I have been trying to sent rcon status to a client. It works, but when you do this your server can't receive and send any packets.
    (I also got a problem with converting the port correctly. That is why i am converting a ip+port to net address.)

    PHP Code:
    case 1203:
    {
        
    #if COD_VERSION == COD2_1_3
            
    typedef enum {
                
    NA_BOT,
                
    NA_BAD,                    // an address lookup failed
                
    NA_LOOPBACK,
                
    NA_BROADCAST,
                
    NA_IP,
                
    NA_IPX,
                
    NA_BROADCAST_IPX
            
    netadrtype_t;

            
    typedef struct {
                
    netadrtype_t    type;

                
    char    ip[4];
                
    char    ipx[10];

                
    unsigned short    port;
            } 
    netadr_t;

            
    typedef struct {
                
    bool    allowoverflow;    // if false, do a Com_Error
                
    bool    overflowed;        // set to true if the buffer size failed (with allowoverflow set)
                
    bool    oob;            // set to true if the buffer size failed (with allowoverflow set)
                
    char    *data;
                
    int        maxsize;
                
    int        cursize;
                
    int        readcount;
                
    int        bit;                // for bitwise reads and writes
            
    msg_t;
                    
            
    char *cmd;
            
    int clientNum;
            
    int helper 0;
            
    helper += stackGetParamString(1, &cmd); // todo: is string?
            
    helper += stackGetParamInt(2, &clientNum);

            if (
    helper 2)
            {
                
    printf_hide("scriptengine> wrongs args for: SV_ConnectionlessPacket(): at least 2 arg\n");
                return 
    stackReturnInt(0);
            }

            
    char ip = (char *)malloc(64);
            
    snprintf(ip64"%s""ip:port");
            
    netadr_t from;
            
    void (*NET_StringToAdr)( const char *snetadr_t *);
            (*(
    int *)&NET_StringToAdr) = 0x0806CD98;
            
    NET_StringToAdr(ipfrom);
                    
            
    char *message = (char *)malloc(1024);
            
    message[0] = -1;
            
    message[1] = -1;
            
    message[2] = -1;
            
    message[3] = -1;
            
    message[4] = 0;

            
    strcat (messagecmd);

            
    printf("Message: %s\n"message);

            
    msg_t msg;
            
    msg->data message;
            
    msg->maxsize 131072;
            
    msg->cursize strlen(msg->data)+1;
            
    msg->readcount 0;
            
    msg->allowoverflow false;
            
    msg->overflowed false;
            
    msg->oob false;
            
    msg->bit 0;

            
    netadr_t adr = *from;

            
    void (*SV_ConnectionlessPacket)( netadr_t frommsg_t msg );
            (*(
    int *)&SV_ConnectionlessPacket) = 0x0809594E;
            
    SV_ConnectionlessPacket(adrmsg);

            return 
    stackPushInt(1);
        
    #else
            
    return stackPushInt(0);
        
    #endif

    My function hook
    PHP Code:
    short ShortSwap (short l)
    {
        
    char    b1,b2;

        
    b1 l&255;
        
    b2 = (l>>8)&255;

        return (
    b1<<8) + b2;
    }

    const 
    char    *NET_AdrToString (netadr_t a)
    {
        static    
    char    s[64];

        if (
    a.type == NA_LOOPBACK) {
            
    strcpy(s"loopback");
        } else if (
    a.type == NA_BOT) {
            
    strcpy(s"bot");
        } else if (
    a.type == NA_IP) {
            
    sprintf(s"%d.%d.%d.%d:%d", (unsigned char)a.ip[0], (unsigned char)a.ip[1], (unsigned char)a.ip[2], (unsigned char)a.ip[3], ShortSwap(a.port));
        } else {
            
    sprintf(s"%ix%ix%ix%i.%ix%ix%ix%ix%ix%ix:%hu",
            (
    unsigned char)a.ipx[0], (unsigned char)a.ipx[1], (unsigned char)a.ipx[2], (unsigned char)a.ipx[3], (unsigned char)a.ipx[4], (unsigned char)a.ipx[5], (unsigned char)a.ipx[6], (unsigned char)a.ipx[7], (unsigned char)a.ipx[8], (unsigned char)a.ipx[9],ShortSwap(a.port));
        }

        return 
    s;
    }

    void hook_ServerCommandnetadr_t frommsg_t *msg )
    {
        
    char msg->data;

        const 
    char * (*NET_AdrToString)( netadr_t a );
        (*(
    int *)&NET_AdrToString) = 0x0806B1D4// this one works better than my own version

        
    printf("From %s\n"NET_AdrToString (from) );
        
    //printf("Max size: %d\n", msg->maxsize);
        //printf("Read count: %d\n", msg->readcount); 
        //printf("Cur size: %d\n", msg->cursize);
        //printf("Bit: %d\n", msg->bit);
        //printf("Ood: %d\n", msg->oob);
        //printf("allowoverflow: %d\n", msg->allowoverflow);
        //printf("overflowed: %d\n", msg->overflowed);
        
    strncpy(d, &d[4], msg->cursize);
        
    printf("Data: %s\n"msg->data);
    }

    cracking_hook_function(0x08097188, (int)hook_ServerCommand); // SVC_RemoteCommand
    cracking_hook_function(0x0809594E, (int)hook_ServerCommand); // SV_ConnectionlessPacket 
    (all the function addresses are for cod2 1.3)

    Printing your own message in console doesn't work either. (same result)
    PHP Code:
    char ip = (char *)malloc(64);
    snprintf(ip64"%s""ip:28960");
    printf("IP: %s\n"ip);
                    
    char *message = (char *)malloc(1024);
    snprintf(message1008"print\n%s"msg);

    printf("Message: %s\n"message);

    netadr_t from;
    void (*NET_StringToAdr)( const char *snetadr_t *);
    (*(
    int *)&NET_StringToAdr) = 0x0806CD98;
    NET_StringToAdr(ipfrom);

    const 
    char * (*NET_AdrToString)( netadr_t a );
    (*(
    int *)&NET_AdrToString) = 0x0806B1D4// this one works better than my own version

    printf("From %s\n"NET_AdrToString (*from) );

    void (*NET_OutOfBandPrint)( netsrc_t socknetadr_t adr, const char *msg );
    (*(
    int *)&NET_OutOfBandPrint) = 0x0806C8CC;
    NET_OutOfBandPrint(NS_SERVER, *frommessage); 
    Last edited by Mitch; 23rd November 2013 at 16:29. Reason: updated to my latest version (still not working)

  2. #2
    Brigadier General
    Join Date
    Dec 2012
    Posts
    1,012
    Thanks
    440
    Thanked 171 Times in 132 Posts
    Sorry for the bump, but why do you want to do that?

  3. #3
    Assadministrator IzNoGoD's Avatar
    Join Date
    Aug 2012
    Posts
    1,718
    Thanks
    17
    Thanked 1,068 Times in 674 Posts
    Might be unrelated: If you put a servercmd in the callback_playercommand BEFORE calling the player playercmd() function, the actual function the player was executing gets overwritten and replaced by the servercommand, which would thus allow for menu-free execclientcmd()

    Might be worth looking into next
    "Does not work" is an error report for a bug between keyboard and chair.

    All hail Artie Effem

  4. #4
    Global Mossaderator Mitch's Avatar
    Join Date
    Nov 2012
    Posts
    654
    Thanks
    204
    Thanked 450 Times in 305 Posts
    Quote Originally Posted by Ni3ls View Post
    Sorry for the bump, but why do you want to do that?
    To print messages like rcon status to a player's console. (instead of using self iprintln("message") )
    But i never could get it working without breaking the server.

    Like ! commands with rcon without a password: !rcon status (for admins)

    Quote Originally Posted by IzNoGoD View Post
    Might be unrelated: If you put a servercmd in the callback_playercommand BEFORE calling the player playercmd() function, the actual function the player was executing gets overwritten and replaced by the servercommand, which would thus allow for menu-free execclientcmd()

    Might be worth looking into next
    I will look into it when i have time for it.

    Edit:
    SV_ExecuteClientCommand
    SV_ClientCommand
    https://github.com/id-Software/Quake...er/sv_client.c
    Last edited by Mitch; 12th December 2014 at 18:28. Reason: added an example

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •