This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Rcon Mod [HL to HL2]

Support & discussion of released scripts, and announcements of new releases.
Post Reply
g
garfwen
Halfop
Posts: 61
Joined: Wed Mar 12, 2008 5:16 pm

Rcon Mod [HL to HL2]

Post by garfwen »

Hello!

Im using RCON-MOD to contol my HL games, and now I would like to make my eggdrop working on HL2 also.

What should be changed on the code?

This is the .c source of the rcon.mod .

Code: Select all

/*
 * This module provides two TCL procedures to eggdrop: challengercon and rcon.
 *
 * challengercon syntax:
 *   challengercon hostname port
 * returns a challenge number from the specified HL server at port
 *
 * rcon syntax:
 *   rcon hostname port challengenumber password command
 * returns the output of "command"
 *
 * Version 1.0
 */
/*
 * Copyright (C) 2001 proton
 * Copyright (C) 2001, 2002 Eggheads Development Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#define MODULE_NAME "rcon"
#define MAKING_RCON
#include "rcon.h" 
#include "../module.h"
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

static Function *global = NULL;

int totalexpmem=0;

//char *rconbuffer;
//static int rconsock;
static int rconlistensock;
static unsigned long rconip;
static p_tcl_bind_list H_rcon;
//static int rcon_listen_port = 43456;
//const int RCON_BUFFER_SIZE = 4096;

static int rcon_expmem() {
  return totalexpmem;
}

static void rcon_report(int idx, int details)
{
  if (details) {
    dprintf(idx, "   using %d bytes\n", rcon_expmem());
    dprintf(idx, "   listening on port: %d\n", rcon_listen_port);
  }
}

unsigned long my_get_ip(char* rcon_host)
{
  struct hostent *hp;
  IP ip;  
  struct in_addr *in;
    
  /* could be pre-defined */
  if (rcon_host[0]) {
    if ((rcon_host[strlen(rcon_host) - 1] >= '0') && (rcon_host[strlen(rcon_host) - 1] <= '9')) {
        return (IP) inet_addr(rcon_host);    
    }
  }  

  hp = gethostbyname(rcon_host);
  if (hp == NULL) {
    return -1;
  }
  in = (struct in_addr *) (hp->h_addr_list[0]);
  ip = (IP) (in->s_addr);
  return ip;
}       
/*
int init_rcon(void)
{
  struct  sockaddr_in sai;

  if ((rconsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    putlog(LOG_DEBUG, "*", "init_rcon socket returned < 0 %d",rconsock);
    return((rconsock = -1));
  }
  memset(&sai, 0, sizeof(sai));
  sai.sin_addr.s_addr = INADDR_ANY;
  sai.sin_family = AF_INET;
  if (bind(rconsock, (struct sockaddr*)&sai, sizeof(sai)) < 0) {
    close(rconsock);
    return((rconsock = -1));
  }
  fcntl(rconsock, F_SETFL, O_NONBLOCK | fcntl(rconsock, F_GETFL));

  return(0);
}
*/

static int init_rcon_sock(void)
{
  struct  sockaddr_in sai;
  int rconsock;

  if ((rconsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    putlog(LOG_DEBUG, "*", "init_rcon socket returned < 0 %d",rconsock);
    return((rconsock = -1));
  }
  memset(&sai, 0, sizeof(sai));
  sai.sin_addr.s_addr = INADDR_ANY;
  sai.sin_family = AF_INET;
  if (bind(rconsock, (struct sockaddr*)&sai, sizeof(sai)) < 0) {
    putlog(LOG_DEBUG, "*", "bind rconsock failed");
    return((rconsock = -2));
  }
  fcntl(rconsock, F_SETFL, O_NONBLOCK | fcntl(rconsock, F_GETFL));

  return(rconsock);
}

static int init_rcon_listen() {
  struct  sockaddr_in sai;

  if ((rconlistensock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    putlog(LOG_MISC, "*", "init_rcon_listen socket returned < 0 %d",rconlistensock);
    return((rconlistensock = -1));
  }
  (void) allocsock(rconlistensock, SOCK_PASS);

  memset(&sai, 0, sizeof(sai));
  sai.sin_family = AF_INET;
  sai.sin_addr.s_addr = htonl(INADDR_ANY);
  sai.sin_port = htons(rcon_listen_port);

  if (bind(rconlistensock, (struct sockaddr*)&sai, sizeof(sai)) < 0) {
    close(rconlistensock);
    return((rconlistensock = -1));
  }
  fcntl(rconlistensock, F_SETFL, O_NONBLOCK | fcntl(rconlistensock, F_GETFL));

  return 1;
}

static int tcl_challengercon STDVAR
{
  struct sockaddr_in sai;
  const char CHALLENGERCON[] = { "ÿÿÿÿchallenge rcon" };
  struct timeval timeout;
  char *buffer = NULL;
  int front, numbytes;
  fd_set hl_sockets;
  unsigned long rconip;
  int rconport;
  char challenge_number[40]="";
  char challenge_number_temp[40]="";
  int rconsock = init_rcon_sock();

  BADARGS(3, 3, " server port");
  rconip = my_get_ip(argv[1]);
  rconport = atoi(argv[2]);


//  debug1("rcon sock: %d", rconsock);

  memset(&sai, 0, sizeof(sai));
  sai.sin_family = AF_INET;
  sai.sin_addr.s_addr = rconip;
  sai.sin_port = htons(rconport);
//  debug2("ip: %D | port: %d", rconip, rconport);

  sendto(rconsock, CHALLENGERCON, strlen(CHALLENGERCON), 0, (struct sockaddr*)&sai, sizeof(sai));

  FD_ZERO(&hl_sockets);
  FD_SET(rconsock,&hl_sockets);
  timeout.tv_sec = 10;
  timeout.tv_usec = 0;

  front = select(FD_SETSIZE,&hl_sockets,NULL,NULL,&timeout);
  if (front < 1) {
     putlog(LOG_MISC, "*", "rconerror: Server not responding (timeout) %d", front);
     Tcl_AppendResult(irp, "-1", NULL);
     return TCL_OK;
  }

        buffer = (char *) nmalloc(RCON_BUFFER_SIZE);
	totalexpmem += RCON_BUFFER_SIZE;
        egg_bzero(buffer, RCON_BUFFER_SIZE);

        numbytes = recv(rconsock, (char *)buffer, RCON_BUFFER_SIZE-1,0);
        if (numbytes == -1) {
                putlog(LOG_MISC, "*", "rconerror: Server not responding");
	        Tcl_AppendResult(irp, "-2", NULL);
		if (buffer) {
			totalexpmem -= RCON_BUFFER_SIZE;
		        nfree(buffer);
			buffer = NULL;
		}
                return TCL_OK;
        }
//  debug2("numbytes: %d | challenge reply: %s", numbytes, buffer);

  strncpyz(challenge_number, buffer, sizeof(challenge_number));
  splitc(challenge_number_temp, challenge_number, ' ');
  splitc(challenge_number_temp, challenge_number, ' ');
  challenge_number[strlen(challenge_number)-1] = '\0';

//  debug1("challenge reply out: %s", challenge_number);

//  challenge_number = buffer[19];
  Tcl_AppendResult(irp, challenge_number, NULL);
  if (buffer) {
    totalexpmem -= RCON_BUFFER_SIZE;
    nfree(buffer);
    buffer = NULL;
  }

  close(rconsock);
  return TCL_OK;
}

static int tcl_sendrcon STDVAR
{
  struct sockaddr_in sai;
  struct stat st;
  const char RCONSTR[] = { "ÿÿÿÿrcon" };
  struct timeval timeout;
  char *buffer = NULL;
  int front, numbytes;
  fd_set hl_sockets;
  unsigned long rconip;
  int rconport, challenge;
  char *cmd = NULL;
  char *newbuffer = NULL;
  int cmdsize;
  int rconsock = init_rcon_sock();

  BADARGS(6, 6, " server port challenge password cmd");
  rconip = my_get_ip(argv[1]);
  rconport = atoi(argv[2]);
  cmdsize = strlen(RCONSTR) + 1 + strlen(argv[3]) + 1 + strlen(argv[4])+2 + 1
            + strlen(argv[5]) + 1;

  cmd = (char *) nmalloc(cmdsize);
  totalexpmem += cmdsize;
  egg_bzero(cmd, cmdsize);  

  sprintf(cmd, "%s %s \"%s\" %s", RCONSTR, argv[3], argv[4], argv[5]);

//  debug3("cmdsize: %d | strlen(cmdsize): %d | cmd: %s", cmdsize, strlen(cmd), cmd);
  memset(&sai, 0, sizeof(sai));
  sai.sin_family = AF_INET;
  sai.sin_addr.s_addr = rconip;
  sai.sin_port = htons(rconport);
  sendto(rconsock, cmd, strlen(cmd), 0, (struct sockaddr*)&sai, sizeof(sai));
  if (cmd) {
    totalexpmem -= cmdsize;
    nfree(cmd);
    cmd = NULL;
  }

  FD_ZERO(&hl_sockets);
  FD_SET(rconsock,&hl_sockets);
  timeout.tv_sec = 6;
  timeout.tv_usec = 0;
             
  front = select(FD_SETSIZE,&hl_sockets,NULL,NULL,&timeout);
  if (front < 1) {
     putlog(LOG_MISC, "*", "rconerror: Server not responding");
     Tcl_AppendResult(irp, "-1", NULL);
     return TCL_OK;
  }

  buffer = (char *) nmalloc(RCON_BUFFER_SIZE);
  totalexpmem += RCON_BUFFER_SIZE;
  egg_bzero(buffer, RCON_BUFFER_SIZE);
  numbytes = recv(rconsock, buffer, RCON_BUFFER_SIZE-1,0);

//  egg_bzero(rconbuffer, RCON_BUFFER_SIZE);
//  Context;
//  numbytes = recv(rconsock, rconbuffer, RCON_BUFFER_SIZE-1,0);

  if (numbytes == -1) {
      putlog(LOG_MISC, "*", "rconerror: Server not responding");
      Tcl_AppendResult(irp, "-2", NULL);
      if (buffer) {
        totalexpmem -= RCON_BUFFER_SIZE;
        nfree(buffer);
        buffer = NULL;
      }

      return TCL_OK;
  }
//  ContextNote(rconbuffer);

  if (numbytes > 4) {  // strip off ÿÿÿÿl [censored]
    newbuffer = buffer + 5;
  } else {
    newbuffer = buffer;
  }

//  debug3("numbytes: %d | buffer: %d | newbuffer: %d", numbytes, strlen(rconbuffer), strlen(newbuffer));
  Tcl_AppendResult(irp, newbuffer, NULL);


  newbuffer = NULL;


  if (buffer) {
    totalexpmem -= RCON_BUFFER_SIZE;
    nfree(buffer);
    buffer = NULL;
  }

  close(rconsock);

  return TCL_OK;
}

static int check_tcl_rcon(char *msg)
{
  Tcl_SetVar(interp, "_rcon1", msg, 0);
  check_tcl_bind(H_rcon, msg, 0, " $_rcon1", MATCH_MASK | BIND_STACKABLE);
}


static void eof_rcon_socket(int idx)
{ 
  putlog(LOG_MISC, "*", "RCON Error: socket closed.");
  killsock(dcc[idx].sock);
  /* Try to reopen socket */
  if (init_rcon_listen()) {
    putlog(LOG_MISC, "*", "RCON socket successfully reopened!");
    dcc[idx].sock = rconlistensock;
    dcc[idx].timeval = now;
  } else
    lostdcc(idx);
} 


static void rcon_socket(int idx, char *buf, int len)
{
  char *buffer = NULL;
  char *bufferptr = NULL;
  int actualsize;

  buffer = (char *) nmalloc(RCON_BUFFER_SIZE);
  totalexpmem += RCON_BUFFER_SIZE;
  actualsize = recv(rconlistensock, buffer, RCON_BUFFER_SIZE,0);

  buffer[actualsize-2] = '\0';  // remove \n\0

  bufferptr = buffer + 4; // remove 4 "-1 bits"

//  buffer = buffer + 4; 

//  putlog(LOG_MISC, "*", buffer);
  check_tcl_rcon(bufferptr);

  bufferptr = NULL;
  if (buffer) {
    totalexpmem -= RCON_BUFFER_SIZE;
    nfree(buffer);
    buffer = NULL;
  }

}

static void display_rcon_socket(int idx, char *buf)
{
  strcpy(buf, "rcon   (ready)");
}

static struct dcc_table DCC_RCON =
{
  "RCON",
  DCT_LISTEN,
  eof_rcon_socket,
  rcon_socket,
  NULL,
  NULL,
  display_rcon_socket,
  NULL,
  NULL,
  NULL
};

static int rcon_1char STDVAR
{
  Function F = (Function) cd;
 
  BADARGS(2, 2, " msg");
  CHECKVALIDITY(rcon_1char);
  F(argv[1]);
  return TCL_OK;
}

static tcl_cmds mytcls[] =
{ 
  {"challengercon",     tcl_challengercon},
  {"rcon",              tcl_sendrcon},
  {NULL,                NULL} 
};

static tcl_ints myints[] =
{
  {"rcon-listen-port",  &rcon_listen_port,   0},
  {NULL,                NULL,                0}
};


static void rcon_rehash() {
  int i, idx;

  for (i = 0; i < dcc_total; i++) {
    if (dcc[i].type == &DCC_RCON) {
      killsock(dcc[i].sock);
      lostdcc(i);
      break;
    }
  }

    idx = new_dcc(&DCC_RCON, 0);
//    if (idx < 0)
//      return "NO MORE DCC CONNECTIONS -- Can't create RCON socket.";

    if (!init_rcon_listen()) {
      lostdcc(idx);
//      return "RCON initialization failed.";
    } else {

    dcc[idx].sock = rconlistensock;
    dcc[idx].timeval = now;
 
    strcpy(dcc[idx].nick, "(rcon)");
    }
}

EXPORT_SCOPE char *rcon_start(Function *);

static char *rcon_close()
{
  int i;

  for (i = 0; i < dcc_total; i++) {
    if (dcc[i].type == &DCC_RCON &&
        dcc[i].sock == rconlistensock) {
      killsock(dcc[i].sock);
      lostdcc(i);
      break;
    }
  }
/*
  if (rconbuffer) {
    totalexpmem -= RCON_BUFFER_SIZE;
    nfree(rconbuffer);
    rconbuffer = NULL;
  }
*/
//  close(rconsock);
  close(rconlistensock);

  del_bind_table(H_rcon);
  del_hook(HOOK_REHASH, (Function) rcon_rehash);
  rem_tcl_commands(mytcls);
  rem_tcl_ints(myints);
  module_undepend(MODULE_NAME);
  return NULL;
}


static Function rcon_table[] =
{
  (Function) rcon_start,
  (Function) rcon_close,
  (Function) rcon_expmem,
  (Function) rcon_report,
  (Function) & H_rcon,
};

char *rcon_start(Function * global_funcs)
{
  int idx;

  if (global_funcs) {
    global = global_funcs;

    module_register(MODULE_NAME, rcon_table, 1, 2);
    if (!module_depend(MODULE_NAME, "eggdrop", 106, 11)) {
      module_undepend(MODULE_NAME);
      return "This module requires Eggdrop 1.6.11 or later.";
    }

//    init_rcon();
//    rconbuffer = (char *) nmalloc(RCON_BUFFER_SIZE);
//    totalexpmem += RCON_BUFFER_SIZE;

    add_tcl_commands(mytcls);
    add_tcl_ints(myints);
    H_rcon = add_bind_table("rcon", HT_STACKABLE, rcon_1char);
    add_hook(HOOK_REHASH, (Function) rcon_rehash);

    idx = new_dcc(&DCC_RCON, 0);
    if (idx < 0)
      return "NO MORE DCC CONNECTIONS -- Can't create RCON socket.";

    if (!init_rcon_listen()) {
      lostdcc(idx);
      return "RCON initialization failed.";
    }

    dcc[idx].sock = rconlistensock;
    dcc[idx].timeval = now;
 
    strcpy(dcc[idx].nick, "(rcon)");

  }  
  return NULL;
}


Thanks,
GaRfWeN
g
garfwen
Halfop
Posts: 61
Joined: Wed Mar 12, 2008 5:16 pm

Post by garfwen »

bump
Post Reply