mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Oct 2009
Posts: 14
N
Pikka bird
OP Offline
Pikka bird
N
Joined: Oct 2009
Posts: 14
Hi all!

I'm writing because I'd like to know your opinion about a solution I'd like to develop.

I'd like to program a bot which will be in about 500 or more channels, receiving in average about 1000 lines/second. All of these lines must be processed in order to find if there's any 'bad word'. So I've been thinking on how to do this, and my solution is using hash tables for expressions and regexp's - resources that mIRC scripts have.

So my questions are the following:

1) Do you think there will be any problem joining all those channels and processing all this text, regarding to RAM memory? in other words, will mIRC crash? is there any limit of channels mIRC can join at a time? There's no problems with flood because that nick will have +o flag.

2) Would there be any problem with rewriting variables if the same code triggers many times at a time?

Thanx for your responses smile

Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
Unless you have control over the network settings, you won't be allowed to join that many channels on any networks I've seen. There is a limit on channels on each network. In addition, mIRC can only open a certain number of windows at a time due to limitations in Windows.

Beyond that, mIRC cannot process that many lines (5 million per second!) that quickly without severe lag.

If you want a bot that stays in that many channels, you should look into an eggdrop or some other similar method. It just won't work well in mIRC.

Also, a bot can still be flooded off regardless of being an OP. The network can kick it for flooding even if you're an op in the channel.

If you run the network, you have more options such as various channel services that you can get that will add protections.


Invision Support
#Invision on irc.irchighway.net
Joined: Dec 2002
Posts: 122
S
Vogon poet
Offline
Vogon poet
S
Joined: Dec 2002
Posts: 122
If you, after reviewing Riamus2 comments still want to use mIRC, I would suggest using sockets, so you don't need to open windows for all the channels you join. This would save alot of resources.

But I agree with Riamus2, for a channel service of that magnitude, I also don't think mIRC is the best way.

Joined: Oct 2009
Posts: 14
N
Pikka bird
OP Offline
Pikka bird
N
Joined: Oct 2009
Posts: 14
Thanx for your responses.

When I meant the bot would have +o mode, I meant it would be an ircop, and on that net with +o flag you don't have a limit on how much channels you can join, so I won't have a problem joining all those channels, and also can't get disconnected for excess flood.

On the other hand, when I said there would be an average of 1000 lines/second I meant counting lines from all channels, not 1000 lines/second/channel.

After that, do you still think it's a bad idea? :-)

Thanx again.

Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
If you get around the window limitation (you can't actually open that many windows in mIRC afaik), you could probably do it at 1000/sec, but it would probably still be slow. The only way to know for certain would be to test it out. As mentioned, sockets should get you around that limitation.

I still think you should just look into one of the channel services that are available for your ircd. They will already have the functionality built in for many kinds of protection as well as other options and features that will likely be useful.

You also have to keep in mind that mIRC is still a client that has to connect to the network. It is possible for it to get disconnected and even for some person to force it to be disconnected through an attack. That's much easier to do with a client than with network services. If you don't want network services, then you really would be better off using an eggdrop bot as its connection will be more stable and it will be faster for what you need.


Invision Support
#Invision on irc.irchighway.net
Joined: Oct 2009
Posts: 14
N
Pikka bird
OP Offline
Pikka bird
N
Joined: Oct 2009
Posts: 14
Thanx again Riamus2 smile

Just to try, do you have or do you know any example on how to do that with Sockets? I'd try it that way.

Thx! smile

Joined: Jan 2010
Posts: 9
L
Nutrimatic drinks dispenser
Offline
Nutrimatic drinks dispenser
L
Joined: Jan 2010
Posts: 9
I once had someone /sajoin me on a network to 250k+ channels, we even had inspircd devs change the way channels were created (epic win for immaturity) and I think the maximum amount of channels mirc would open was around 490, my mirc didn't crash either, which I was proud of laugh

Perhaps running multiple instances of mirc and creating a botnet might be a better option.

Last edited by Litch; 07/08/10 05:30 AM.
Joined: Oct 2009
Posts: 14
N
Pikka bird
OP Offline
Pikka bird
N
Joined: Oct 2009
Posts: 14
Thanx for the info Litch smile

However, if someone could tell me where to get an example of what STING and Riamus2 wrote, opening channels with sockets, I'd be very grateful for it. Actually, it's not my decision to make it that way, but I've been asked to do it :P

Thank you very much!

Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
I've written up an example socket bot that will connect to a server (just the one -- multiserver is more complex) and respond to certain events.

This is just to show you how socket bots work. It is in no way a complete of even very functional bot.

The bot has a built in identd server so you can respond to identd requests with it.

Commands:

/bot connect <server> <port> (to connect the bot to a server)
/bot disconnect (to disconnect the bot)
/bot send (to send data to the server)
/bot sendln (to send data to the server follows by a CRLF)
/bot debug (to open a window which shows all incoming/outgoing data and allows you to send data to the server by typing commands out)
/bot identresponse <data> (to respond to ident requests) -- you won't need this, I've already scripted the ident response but you can see how to do it at least smile

I have also added a small /test alias that will open up the debug window and connect you a server. You will want to make use of the debug window whilst you're writing the bot. You'll need to change the test alias to connect to a server/port of your choice.

When commands are received from the server it will throw off signals that you can respond to using the ON SIGNAL event. For the time being all signals will be echoed to the status window so that you can see what the signals look like and choose how to respond to each one.

At the moment the bot doesn't join any channels automatically but you can make it join a channel by typing "JOIN #channel" in the debug window without the quotes.

The bot keeps a list of channels it has joined, it keeps track of its own nickname and it keeps track of a nicklist for each channel, however I have only incorporated the JOIN, PART, NICK and QUIT events for the nicklist tracking.. you will need to add support for on KICK. This is just an example bot, after all.

If you look towards the end of the script you will see how to respond to the signal events that are thrown.


For example:

Code:
elseif ($1 == IRCEVENT.PART) {
    if ($trimnick($2) == $bme) hdel bot.channels $3
    else hdel bot.nicklist. $+ $3 $trimnick($2)
  }
  ; /names list.
  elseif ($1 == IRCEVENT.RAW.353) {
    var %hash = bot.nicklist. $+ $4 
    tokenize 32 $mid($5-,2)
    while ($1 != $null) {
      hadd -m %hash $trimstatus($1) $trimstatus($1)
      tokenize 32 $2-
    }
  }


The first event above is the part that updates the nicklist when somebody leaves a channel.

The second event above is the part that fills the nicklist when a /names list is received back from the server (usually when you first join a channel).

Anyway, that's the example. If you're serious about making this I suggest you study the code and play around with the signals, and try to get things done. If you get stuck I'll be willing to help you with more questions but I'm not going to write the entire thing for you smile

Without further ado, here's the code.

Code:
alias -l err {
  echo -ac info $1-
  halt
}
alias -l bclose {
  if ($window(@bot.debug)) echo $v1 4*** Disconnected ***
  sockclose bot*
  hfree -w bot*
}
alias -l trimaddress return $gettok($1,2-,33)
alias -l trimnick return $trimstatus($mid($gettok($1,1,33),2))
alias -l trimstatus return $regsubex($1,/^[@%\+]+/,)

alias test {
  close -@ @bot.debug
  bot debug
  bot connect <your server> <your port>
}

alias -l menubchannel {
  if ($istok(begin end,$1,32)) return -
  var %c = $hget(bot.channels,$1).item
  return %c : viewnlist %c
}
alias -l viewnlist {
  var %h = bot.nicklist. $+ $1, %i = 1
  echo @bot.debug 7*** Nicklist for $1:
  while ($hget(%h,%i).item != $null) {
    echo @bot.debug 7 $+ $v1 ( $+ $hget(%h,%i).data $+ )
    inc %i
  }
}

alias bchannel return $hget(bot.channels,$1).item
alias bme return $hget(bot,nick)

alias bot {
  if ($1 == connect) {
    if ($sock(bot)) err * /bot: already connected.
    if ($0 < 3) err * /bot: insufficient parameters.
    if ($3 !isnum 1-65535) err * /bot: invalid port specified.
    sockopen bot $2-3
  }
  elseif ($istok(send sendln,$1,32)) {
    if (!$sock(bot)) err * /bot: not connected.
    if ($0 < 2) err * /bot: insufficient parameters.
    if ($window(@bot.debug)) echo @bot.debug 5>>> $2- $+ $iif($1 == sendln,\r\n)
    sockwrite $iif($1 == sendln,-n) bot $2-
  }
  elseif ($1 == disconnect) {
    if (!$sock(bot)) err * /bot: not connected.
    bclose
  }
  elseif ($1 == identresponse) {
    if ($0 < 4) err * /bot: insufficient parameters.
    if (!$sock(bot.identd.client)) err * /bot: no ident request in progress.
    sockwrite -n bot.identd.client $2-3 : USERID : UNIX : $4
  }
  elseif ($1 == debug) && (!$window(@bot.debug)) window -e @bot.debug
}

on *:input:@bot.debug: bot sendln $1-
menu @bot.debug {
  Quit: bot sendln QUIT
  Disconnect: bot disconnect
  View channels:{
    var %i = 1
    while ($hget(bot.channels,%i).item) {
      tokenize 32 $1- $v1
      inc %i
    }
    echo -a 7* ON CHANNELS: $1-
  }
  View nicklist
  .$submenu($menubchannel($1))
}

on *:sockopen:bot:{
  if ($sockerr) {
    bclose
    err * /bot: socket error ( $+ $sock(bot).wserr $+ : $sock(bot).wsmsg $+ )
  }
  socklisten bot.identd 113
  .signal -n bot CONNECT
}
on *:socklisten:bot.identd: sockaccept bot.identd.client
on *:sockread:bot.identd.client:{
  var %data
  sockread %data
  .signal -n bot IDENT %data
}
on *:sockwrite:bot.identd.client: sockclose bot.identd*
on *:sockread:bot:{
  var %data
  sockread %data
  tokenize 32 %data
  if ($window(@bot.debug)) echo @bot.debug 3<<< $1-\r\n
  if ($2 isnum) {
    if ($2 == 005) .signal -n bot LOGON $3-
    .signal -n bot IRCEVENT.RAW. $+ $2-
  }
  elseif ($1 == PING) .signal -n bot IRCEVENT.PING $2-
  elseif ($1 == ERROR) .signal -n bot IRCEVENT.ERROR $2-
  else .signal -n bot IRCEVENT. $+ $2 $1 $3-
}
on *:sockclose:bot: bclose

on *:signal:bot:{
  echo -s SIGNAL: $1-
  if ($1 == IDENT) bot identresponse $2-3 bot
  elseif ($1 == CONNECT) {
    bot sendln NICK botty_
    bot sendln USER botty_ 8 * :bot
  }
  elseif ($1 == LOGON) {
    hadd -m bot nick $2
    hadd -m bot serversupports $3-
  }
  elseif ($1 == IRCEVENT.PING) bot sendln PONG $2-
  elseif ($1 == IRCEVENT.JOIN) {
    if ($trimnick($2) == $bme) hadd -m bot.channels $mid($3,2) $ticks
    else hadd -m bot.nicklist. $+ $mid($3,2) $trimnick($2) $mid($2,2)
  }
  elseif ($1 == IRCEVENT.NICK) {
    if ($trimnick($2) == $bme) hadd -m bot nick $mid($3,2)
    else {
      var %i = 1, %c
      while ($bchannel(%i)) {
        %c = $v1
        if ($hget(bot.nicklist. $+ %c,$trimnick($2))) {
          hdel bot.nicklist. $+ %c $trimnick($2)
          hadd -m bot.nicklist. $+ %c $mid($3,2) $+($mid($3,2),!,$trimaddress($2))
        }
        inc %i
      }
    }
  }
  elseif ($1 == IRCEVENT.QUIT) {
    if ($trimnick($2) == $bme) bclose
    else {
      var %i = 1, %c
      while ($bchannel(%i)) {
        %c = $v1
        if ($hget(bot.nicklist. $+ %c,$trimnick($2))) hdel bot.nicklist. $+ %c $trimnick($2)
        inc %i
      }
    }
  }
  elseif ($1 == IRCEVENT.PART) {
    if ($trimnick($2) == $bme) hdel bot.channels $3
    else hdel bot.nicklist. $+ $3 $trimnick($2)
  }
  ; /names list.
  elseif ($1 == IRCEVENT.RAW.353) {
    var %hash = bot.nicklist. $+ $4 
    tokenize 32 $mid($5-,2)
    while ($1 != $null) {
      hadd -m %hash $trimstatus($1) $trimstatus($1)
      tokenize 32 $2-
    }
  }
}


Hope this helps smile


Link Copied to Clipboard