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 help

Help for those learning Tcl or writing their own scripts.
Post Reply
T
TEK7
Voice
Posts: 10
Joined: Sat Apr 10, 2010 10:49 am

Rcon MOD help

Post by TEK7 »

I have rcon mod installed, and matchbot.tcl. I configured my server etc.. But i'm receiving that error

Code: Select all

rconerror: Server not responding
Can help me? :/

Code: Select all

# Server ip address/hostname
set rhost "counterstrike.server.com"

# Server port
set rport "27015"

# Rcon password
set rconpass "blah"


#################################################
## Shouldn't need to change anything down here ##
#################################################

set matchchan ""
set challenge [challengercon $rhost $rport]
set mb_teamsay 1
set mb_say 1
set mb_maxnamelength 15

array set kills {}
array set deaths {}


bind rcon - * rconmsg

proc rconmsg {msg} {
  global rhost rport my-ip
  global mb_teamsay mb_say matchchan

  regexp {log L [^ ]+ - [0-9]{2}:[0-9]{2}:[0-9]{2}: (.+)} $msg orig msg

#  putlog $msg

  if {[regexp {\"(.+)\" attacked \"(.+)\" with \"(.+)\" \(damage \"([0-9]+)\"\) \(damage_armor \"([0-9]+)\"\) \(health \"(.+)\"\) \(armor \"([0-9]+)\"\)} $msg all nk1 nk2 gun damage damage_armor health armor]} {
    # do nothing. ignore.
  } elseif { [regexp {^Rcon: .+$} $msg] } {
      if {[regexp {Rcon: \"rcon .+ logaddress (.+) (.+)\" from \"(.+)\"} $msg all loghost logport address] && $loghost != ${my-ip}} {
          if {$matchchan == ""} {
              putrconchan "Uh oh...logaddress was changed to $loghost $logport by $address..."
          } else {
              putrconchan "Uh oh...logaddress was changed to $loghost $logport by $address...getting it back"
              getrconlog
          }
      } else {
          putlog $msg
      }
  } elseif { [regexp {^Server cvars .+$} $msg] } {
    putlog $msg
  } elseif { [regexp {^Server cvar .+$} $msg] } {
    putlog $msg
  } elseif { [regexp {^Log file .+$} $msg] } {
    putlog $msg
  } elseif { [regexp {^\[ADMIN\] .+$} $msg] } {
    putlog $msg
  } elseif { [regexp {^\[META\] .+$} $msg] } {
    putlog $msg
  } elseif { [regexp {^Server say \"(.+)\"} $msg all s] } {
    putrconchan "\002Server\002: $s"
  } elseif { [regexp {^World triggered \"(.+)\"} $msg all txt] } {
    if {[string compare $txt "Round_End"] == 0} {
    } elseif {[string compare $txt "Round_Start"] == 0} {
      putrconchan "$msg"
    } else {
      putrconchan "$msg"
    }
 } elseif { [regexp {^Team \"(.+)\" scored \"(.+)\" with \"(.+)\" players} $msg all team score players] } {
    putrconchan "\002$team score:\002 $score"
    resetkills
    resetdeaths
 } elseif { [regexp {^Team \"(.+)\" triggered \"(.+)\" \(CT \"([0-9]+)\"\) \(T \"([0-9]+)\"\)} $msg all team txt scorect scoret] } {
    putrconchan "$msg"
  } elseif {[regexp {\"(.+)\" killed \"(.+)\" with \"(.+)\"} $msg all nk1 nk2 gun]} {
   
    set sid1 [serverid $nk1]
    set sid2 [serverid $nk2]
    
    # team kill
    if {[team $nk1] == [team $nk2]} {
      updatekills $sid1  -1
      updatedeaths $sid2 1
    } else { # regular kill
      updatekills $sid1 1
      updatedeaths $sid2 1
    }
    
    putrconchan "[parsename $nk1] killed [parsename $nk2] with \00303$gun\003"
  } elseif {[regexp {\"(.+)\" say \"(.+)\"(.*)} $msg all nk1 txt dead]} {
    if {$mb_say} {
      if {[string compare $dead " (dead)"] == 0} {
        putrconchan "*DEAD*[parsename $nk1]: \00303$txt\003"
      } else {
        putrconchan "[parsename $nk1]: \00303$txt\003"
      }
    }
  } elseif {[regexp {\"(.+)\" say_team \"(.+)\"(.*)} $msg all nk1 txt dead]} {
    if {$mb_teamsay} {
      if {[string compare $dead " (dead)"] == 0} {
        putrconchan "*DEAD*[parsename $nk1] (team): \00303$txt\003"
      } else {
        putrconchan "[parsename $nk1] (team): \00303$txt\003"
      }
    }
  } elseif {[regexp {\"(.+)\" changed name to \"(.+)\"} $msg all nk1 nk2]} {
    putrconchan "[parsename $nk1] changed name to $nk2"
  } elseif {[regexp {\"(.+)\" triggered \"(.+)\"} $msg all nk1 txt]} {
    if {[string compare $txt "Begin_Bomb_Defuse_With_Kit"] == 0} {
      putrconchan "[parsename $nk1] is defusing the bomb with a kit"
    } elseif {[string compare $txt "Begin_Bomb_Defuse_Without_Kit"] == 0} {
      putrconchan "[parsename $nk1] is defusing the bomb without a kit"
    } elseif {[string compare $txt "Planted_The_Bomb"] == 0} {
      putrconchan "[parsename $nk1] planted the bomb"
    } elseif {[string compare $txt "Got_The_Bomb"] == 0} {
      putrconchan "[parsename $nk1] got the bomb"
    } elseif {[string compare $txt "Dropped_The_Bomb"] == 0} {
      putrconchan "[parsename $nk1] dropped the bomb"
    } elseif {[string compare $txt "Spawned_With_The_Bomb"] == 0} {
      putrconchan "[parsename $nk1] has the bomb"
    } elseif {[string compare $txt "Defused_The_Bomb"] == 0} {
      putrconchan "[parsename $nk1] defused the bomb!"
    } else {
      putrconchan "[parsename $nk1] triggered $txt"
    }
  } elseif {[regexp {\"(.+)\" committed suicide with \"(.+)\"} $msg all nk1 txt]} {  
    set sid1 [serverid $nk1]
    
    updatedeaths $sid1 1
    
    putrconchan "[parsename $nk1] committed suicide with $txt"
  } elseif {[regexp {\"(.+)\" joined team \"(.+)\"} $msg all nk1 newteam]} {
    putrconchan "\002[parsename $nk1]\002 joined the $newteam team"
  } elseif {[regexp {\"(.+)\" disconnected} $msg all nk1]} {
    putrconchan "[parsename $nk1] disconnected"
  } elseif {[regexp {\"(.+)\" connected, address \"(.+)\"} $msg all nk1 address]} {
    putrconchan "\002[parsename $nk1]\002 <$address> connected"
  } elseif {[regexp {\"(.+)\" entered the game} $msg all nk1]} {
    updatekills [serverid $nk1] 0
    updatedeaths [serverid $nk1] 0
    putrconchan "\002[parsename $nk1]\002 entered the game"
  } elseif {[regexp {Loading map \"(.+)\"} $msg all map]} {
    putrconchan "Loading map: $map"
  } elseif { [regexp {^Bad Rcon: .+$} $msg] } {
    putlog $msg
  } else {
    putrconchan $msg
    putlog "Unknown: $msg"
  }
}

proc parsename {name} {
  global kills deaths mb_maxnamelength
  
  if {[regexp {(.+)<([0-9]+)><[0-9]+><([A-Z]*)>} $name all nk sid team]} {
    if {[string compare $team "TERRORIST"] == 0} {
      return [format "\00304%-${mb_maxnamelength}.${mb_maxnamelength}s\003 \[%-2d/%2d\]" $nk [getkills $sid] [getdeaths $sid]]
    } elseif {[string compare $team "CT"] == 0} {
      return [format "\00312%-${mb_maxnamelength}.${mb_maxnamelength}s\003 \[%-2d/%2d\]" $nk [getkills $sid] [getdeaths $sid]]
    } else {
      return "$nk"
    }
  } else {
    return $name
  }
}

proc team {name} {
  if {[regexp {.+<[0-9]+><[0-9]+><([A-Z]*)>} $name all team]} {
    return $team
  } else {
    return ""
  }
}


proc serverid {name} {
  if {[regexp {.+<([0-9]+)><[0-9]+><[A-Z]*>} $name all serverid]} {
    return $serverid
  } else {
    return "0"
  }
}

proc getrconlog {} {
    global rhost rport challenge my-ip rcon-listen-port rconpass
    set response [myrcon "logaddress ${my-ip} ${rcon-listen-port}"]
}

proc putrconchan {msg} {
  global matchchan

  dccputchan 1 $msg

  if {$matchchan != ""} {
    putquick "PRIVMSG $matchchan :$msg"
  }
  
}

proc updatekills {sid incr} {
  global kills
  
  if {$incr == 0} {
    set kills($sid) 0
  } elseif {[info exists kills($sid)]} {
    incr kills($sid) $incr
  } else {
    set kills($sid) $incr
  }
}

proc resetkills {} {
  global kills

  array unset kills  
}

proc getkills {sid} {
  global kills

  if {[info exists kills($sid)]} {
    return $kills($sid)
  } else {
    return 0
  }
}

proc updatedeaths {sid incr} {
  global deaths
  
  if {$incr == 0} {
    set deaths($sid) 0
  } elseif {[info exists deaths($sid)]} {
    incr deaths($sid) $incr
  } else {
    set deaths($sid) $incr
  }
}

proc resetdeaths {} {
  global deaths

  array unset deaths
}

proc getdeaths {sid} {
  global deaths

  if {[info exists deaths($sid)]} {
    return $deaths($sid)
  } else {
    return 0
  }
}

proc matchbot {nickname ident handle channel argument } {
  global matchchan rhost rport challenge rconpass rcon-listen-port my-ip
  global mb_say mb_teamsay mb_maxnamelength

  set cmd [lindex $argument 0]
  set args [lrange $argument 1 end]

  resetkills
  resetdeaths

  if {$cmd == "stop"} {
    clearqueue help
    putquick "PRIVMSG $channel :Stopped matchbot"
    set matchchan ""
  } elseif {$cmd == "start"} {
    if {$args != ""} {
        set matchchan $args
    } else {
        set matchchan $channel
    }

    getrconlog
    putquick "PRIVMSG $channel :Starting matchbot in \"$matchchan\""
    putquick "PRIVMSG $channel :Parameters: (say $mb_say) (teamsay $mb_teamsay) (maxnamelength $mb_maxnamelength)"
  } elseif {$cmd == "set"} {
    set var [lindex $args 0]
    set val [lindex $args 1]

    if {$var == "say"} {
      if {$val == ""} {
        putquick "PRIVMSG $channel :mm1 display is set to $mb_say"
      } else {
        if {$val == "1" || $val == "on"} {
          set mb_say 1
        } else {
          set mb_say 0
        }

        putquick "PRIVMSG $channel :mm1 display was changed to $mb_say"
      }

    } elseif {$var == "teamsay"} {
      if {$val == ""} {
        putquick "PRIVMSG $channel :say_team display is set to $mb_teamsay"
      } else {
        if {$val == "1" || $val == "on"} {
          set mb_teamsay 1
        } else {
          set mb_teamsay 0
        }

        putquick "PRIVMSG $channel :say_team display was changed to $mb_teamsay"
      }

    } elseif {$var == "maxnamelength"} {
      if {$val == "" || ![string is integer $val]} {
        putquick "PRIVMSG $channel :Max name length is set to $mb_maxnamelength"
      } else {
        set mb_maxnamelength $val

        putquick "PRIVMSG $channel :Max name length was changed to $mb_maxnamelength"
      }
    } else {
      putserv "NOTICE $nickname :Syntax: @matchbot set <cmd> \[on|off|value\]"
      putserv "NOTICE $nickname :Commands:"
      putserv "NOTICE $nickname :  maxnamelength \[#\]  :: Sets the max name length to \002\#\002, for display purposes"
      putserv "NOTICE $nickname :  say \[on|off\]  :: Sets the display of message mode 1 data \002on\002 or \002off\002"
      putserv "NOTICE $nickname :  teamsay \[on|off\]  :: Sets the display of message mode 2 data (team_say) \002on\002 or \002off\002"
    }

  } else {
    putserv "NOTICE $nickname :ki server matchbot syntax:"
    putserv "NOTICE $nickname :@matchbot start \[target\]  ::  Starts a matchbot in \002target\002, or the current channel if \002target\002 is not specified"
    putserv "NOTICE $nickname :@matchbot stop  ::  Stops matchbot"
    putserv "NOTICE $nickname :@matchbot set <parameter> \[value\]   ::  Sets or displays matchbot parameters :: \002@matchbot set\002 for more info"
  }


  return 1
}

bind pub o|o @matchbot matchbot


proc rconsay {nickname ident handle channel argument } {
  global rhost rport rconpass challenge

  if {$argument == ""} {
    putserv "PRIVMSG $channel :Syntax: @say <text>"
  } else {
    set response [myrcon "say $argument"]
    putserv "PRIVMSG $channel :$response"
  }

  return 1
}

bind pub o|o @say rconsay

proc rconmap {nickname ident handle channel argument } {
  global rhost rport rconpass challenge

  if {$argument == ""} {
    putserv "PRIVMSG $channel :Syntax: @map <map>"
  } else {
    set response [myrcon "changelevel $argument"]
    putserv "PRIVMSG $channel :$response"
  }

  return 1
}

bind pub o|o @map rconmap

proc rconexec {nickname ident handle channel argument } {
  global rhost rport rconpass challenge
  if {$argument == ""} {
    putserv "PRIVMSG $channel :Syntax: @rcon <cmd>"
  } else {
    set response [myrcon $argument]
    putserv "PRIVMSG $channel :$response"
  }

  return 1
}

bind pub o|o @rcon rconexec

bind pub o|o @challenge rconchallenge

proc rconchallenge {nickname ident handle channel argument } {
      global rhost rport challenge
      set challenge [challengercon $rhost $rport]
      putserv "PRIVMSG $channel :Challenge received"
}

proc myrcon {mycmd} {
  global rhost rport rconpass challenge

  set response [rcon $rhost $rport $challenge "$rconpass" $mycmd]

  if {[regexp {Bad challenge.} $response all] || [regexp {No challenge for your address.} $response all]} {
      set challenge [challengercon $rhost $rport]
      set response [rcon $rhost $rport $challenge "$rconpass" $mycmd]
  }

  return $response
}
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Doublecheck your ip, udp-port, and whether there are any firewalls interfering with the connection.
NML_375
T
TEK7
Voice
Posts: 10
Joined: Sat Apr 10, 2010 10:49 am

Post by TEK7 »

when i send @map de_dust2, the bot sends "-1"
Have any way to change listen port?

Code: Select all

Rcon: "rcon 1488482803 "xxxx" changelevel de_dust2" from "89.109.74.95:62301"
"62301" that is random, any to change to put a unique port?

here souce code of 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;
}

Post Reply