Question

Currently I have an irc bot that when a user says a keyword e.g test1 they get +1 added to their count, which is stored in a file. However I wanted to know who had the biggest count (who was winning). I thought something like a while loop would work, looking for the numbers against the nickname, unfortunately, although my pseudo code is correct, the theoretical code, not so much.

This is what I have so far.

on *:TEXT:!winning:#:{
  var %i = 1, %highest = 0, %mycookie = $readini(cookies.ini,n,#,$nick)

  while (%i < $lines(cookies.ini)) {
    if (%mycookie > %highest) {
      %highest = %mycookie
          if (%highest == 1) {
      msg $chan $nick is winning with %highest count. }
      elseif (%highest > 1) {
      msg $chan $nick is winning with %highest counts. }
      else {
            msg $chan No one has any count! Must try harder! }
    }
        else { return }  
    inc %i
  }
}

I'm looking to cycle through the file and whenever it finds a higher number than %highest (which starts at 0) put this into the variable, and move to the next name. Similarly, I'm aware that using $nick is wrong as that will display MY nickname, instead of grabbing the nickname from the file... can I grab the nickname from the file?

Thanks

Similarly, on a completely unrelated note. Is there a way in mIRC to use a different script file per channel? Something like:

if ($chan == #mychan) {
  $remote == script1.ini }
else { }
Was it helpful?

Solution

You can loop through the contents of an INI file using the $ini() identifier. $ini(cookies.ini, $chan, 0) will return the total of people with a record on that channel, whereas $ini(cookies.ini, $chan, N) will return the name of the Nth person (which can then be passed as the last parameter in $readini()).

Furthermore, don't include the messages with the if/elseif/else structure inside the while loop; you'll probably want to message the outcome once, after the highest record has been found:

on *:TEXT:!winning:#:{
  var %i = 1, %highestCookies = 0, %highestUser

  ; This will run as long as %i is smaller than or equal to the number of lines in the ini section $chan
  while (%i <= $ini(cookies.ini, $chan, 0)) {

    ; As we loop through the file, store the item name (the nickname) and the cookies (the value) 
    var %user = $ini(cookies.ini, $chan, %i), %cookies = $readini(cookies.ini, n, $chan, %user)

    ; Is this the highest found so far?
    if (%cookies > %highestCookies) {
      var %highestCookies = %cookies
      var %highestUser = %user
    }

    inc %i
  }

  ; Now that we have the correct values in our variables, display the message once
  if (%highestCookies == 1) {
    msg $chan %highestUser is winning with %highestCookies count.
  }
  elseif (%highestCookies > 1) {
    msg $chan %highestUser is winning with %highestCookies counts.
  }
  else {
    msg $chan No one has any count! Must try harder!
  }
}

Edit: Fixed an issue that caused no higher values to be found because %highestCookies was assigned a $null value instead of 0.


As for your second question, it's not possible to have different script files for different channels. However, you could modify the location parameter in the event catchers so it only catchers events on specific channels. As an example, this is how an on TEXT would look like:

; This event will only listen to the word "hello" in #directpixel and #stackoverflow
on *:TEXT:hello:#directpixel,#stackoverflow:{
  msg $chan Hello $nick $+ !
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top