mIRC Home    About    Download    Register    News    Help

Print Thread
#273095 15/01/25 07:15 PM
Joined: Nov 2021
Posts: 125
Simo Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Nov 2021
Posts: 125
Greetings,

im trying to write an auto bans removal using ping from server rather then rely on timers to then check enabled channels where i want to auto ban removal to work this is what i have so far:

Code

ON *:PING:{ 
  var %i = 1 | while ($gettok($regsubex($str(x,$chan(0)),/x/g,$chan(\n) $chr(32)),%i,32)) {
    var %chnel =  $v1
    if ($nick(%chnel,$me,~&@%)) {
      check if %chnel is enabled to check for auto bans removal then do mode %chnel 
     and redirect to raw numeric to check ban duration and ban if exceeded ban duration
    }
    inc %i
  }
}


RAW 367:*:{
  if (($calc( $ctime - $5 ) > 7200 ) && (!$istok(%ban_except,$3,32)) {
    if (!%bcount) { set %bcount 0  }
    if (%bcount <= $calc( $modespl - 1 )) { set %blist $3 %blist | inc %bcount }
    if (%bcount > $calc( $modespl - 1 )) {  putmode $2 $+(-,$str(b,%bcount)) $($+(%,blist),2) | unset %bcount | unset %blist }
    halt
  }
}


RAW 368:*:{ if (%bcount) { unset %bcount } | if (%blist) { unset %blist } | halt }


Joined: Dec 2002
Posts: 254
T
Fjord artisan
Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 254
I'm not entirely sure what %ban_except is, I assume you wish to work with multiple lists: beI (and possibly q) bans, excepts, invites, and quiets.

Rather than making the problem more complex than it needs to be, why not take advantage of mIRC's built-in lists? It makes more sense to test $chan(X).ibl/iel/iil/iql to see if you've already called these and have them up-to-date in mIRC's internal list history, which will avoid constantly re-requesting said lists from the IRCd per channel upon every ping.

This also gives you a more convenient way to iterate over said lists without the headache and frustration of raw numerics and what token represents what data.

Code
$chan(1).ibl/iel/iil/iql return $true if mIRC has already seen a /mode +b/e/I/q and has a ban/exception/invite/quiet list for the channel, $false otherwise

$ibl(#channel,N)
$iel(#channel,N)
$iil(#channel,N)
$iql(#channel,N)

Returns Nth item in the internal ban/exception/invite/quiet list, or if N is 0 returns total number of items in that list.

Properties: by, date, ctime

Below is one example (I believe fairly well documented which makes it look huge) of how to achieve what you're after:
Modify %lists with the list type(s) you want. (Line 12)
Modify %MaxLifespan to set the duration to meet or exceed to unset. (line 52)
Code
on *:PING: {
  ;== Use $comchan to find our total chans we're ACTIVELY on, as $chan() itself returns ones we may not be in, depending on mIRC settings like keeping chan windows
  ; open on kick/part/disconnect/etc... and make a tokenized list of these channels in "%chans"
  var %x = 0 , %total = $comchan($me,0) , %chans = $regsubex($str($chr(32),$calc(%total - 1)),//g,$comchan($me,\n))

  ;== Iterate through all the ACTIVE channels we're on
  while (%x < %total) {
    var %x = %x + 1 , %chan = $gettok(%chans,%x,32)

    ;== %Lists are the types you wish to "monitor" b is Bans, e is Excepts, I is Invites, q is Quiets (tho not on all networks)
    ;Modify "%lists" to suit your needs.
    var %lists = beIq , %known = $gettok($chanmodes,1,44) 

    ;== Copy is used to tell the "helper alias" what lists we're working with. the regsubex expunges any list types not found from 005 CHANMODES= (not all servers support beIq)
    var %copy = $regsubex(%lists,/(.)/g,$iif(\t isincs %known,\t))

    ;== If you are some level of OP on chan...
    if ($nick(%chan,$me,~&@%)) {
      ;== If said list is "loaded" already, remove it's character from the lists variable
      ; or IF raw 005 on connect (which fills $chanmodes) doesn't contain that type of list, remove it.
      if ($chan(%chan).ibl || b !isincs %known) { var %lists = $replacecs(%lists,b,$null) }
      if ($chan(%chan).iel || e !isincs %known) { var %lists = $replacecs(%lists,e,$null) }
      if ($chan(%chan).iil || I !isincs %known) { var %lists = $replacecs(%lists,I,$null) }
      if ($chan(%chan).iql || q !isincs %known) { var %lists = $replacecs(%lists,q,$null) }

      ;== If any of the lists aren't filled yet, request them from the server.
      if (%lists) { mode %chan + $+ %lists }

      ;== Immediately call our "helper alias" to do stuff with the internal lists mIRC has stored. (If any left supported)
      ; It will trigger a callback timer if the list isn't yet filled by the time of execution from requesting them on the if statement above.
      if (%copy) { ExpungeList %chan %copy }
    }
  }
}
alias ExpungeList {
  var %chan = $1 , %lists = $2 , %copy = $2

  ;== If said list is "loaded" already, remove it's character from the lists variable
  if ($chan(%chan).ibl) { var %lists = $replacecs(%lists,b,$null) }
  if ($chan(%chan).iel) { var %lists = $replacecs(%lists,e,$null) }
  if ($chan(%chan).iil) { var %lists = $replacecs(%lists,I,$null) }
  if ($chan(%chan).iql) { var %lists = $replacecs(%lists,q,$null) }

  ;== If any of the lists aren't filled yet, set a timer to re-call this alias as the above "should" have requested the list type(s) from the ping event.
  ;include connection ID in the timer name to avoid potential timer clash with multiple networks same channel name.
  if (%lists) { $+(.timer,%chan,.,$cid,.ExpungeList) 1 1 ExpungeList $1- }

  ;== If we get here, the lists must be cached... Attempt to do work with them
  else {
    ;== Number of seconds that must be met or exceeded to be flagged as "auto-remove" (7200 == 2 hours)
    ; Modify this to suit your needs.
    var %MaxLifespan = 7200

    ;= Bans
    if (b isincs %copy) {
      var %x = 0 , %tot = $ibl(%chan,0)
      while (%x < %tot) {
        var %x = %x + 1 , %duration = $ctime - $ibl(%chan,%x).ctime

        ;== If this mask has met or exceeded the maximum lifespan, add it to a tokenized list.
        if (%duration >= %MaxLifespan) { var %ExpungeBans = $addtok(%ExpungeBans,$ibl(%chan,%x),32) }
      }
    }

    ;= Excepts
    if (e isincs %copy) {
      var %x = 0 , %tot = $iel(%chan,0)
      while (%x < %tot) {
        var %x = %x + 1 , %duration = $ctime - $iel(%chan,%x).ctime

        ;== If this mask has met or exceeded the maximum lifespan, add it to a tokenized list.
        if (%duration >= %MaxLifespan) { var %ExpungeExcepts = $addtok(%ExpungeExcepts,$iel(%chan,%x),32) }
      }
    }

    ;= Invites
    if (I isincs %copy) {
      var %x = 0 , %tot = $iil(%chan,0)
      while (%x < %tot) {
        var %x = %x + 1 , %duration = $ctime - $iil(%chan,%x).ctime

        ;== If this mask has met or exceeded the maximum lifespan, add it to a tokenized list.
        if (%duration >= %MaxLifespan) { var %ExpungeInvites = $addtok(%ExpungeInvites,$iil(%chan,%x),32) }
      }
    }

    ;= Quiets
    if (q isincs %copy) {
      var %x = 0 , %tot = $iql(%chan,0)
      while (%x < %tot) {
        var %x = %x + 1 , %duration = $ctime - $iql(%chan,%x).ctime

        ;== If this mask has met or exceeded the maximum lifespan, add it to a tokenized list.
        if (%duration >= %MaxLifespan) { var %ExpungeQuiets = $addtok(%ExpungeQuiets,$iql(%chan,%x),32) }
      }
    }

    ;== Spit out some data on the masks we collected per type
    if (%ExpungeBans) { echo -ai2 *** Bans on: %chan to remove: $v1 }
    if (%ExpungeExcepts) { echo -ai2 *** Excepts on: %chan to remove: $v1 }
    if (%ExpungeInvites) { echo -ai2 *** Invites on: %chan to remove: $v1 }
    if (%ExpungeQuiets) { echo -ai2 *** Quiets on: %chan to remove: $v1 }

    ;== Here's where you can do your fancy split-up by $modespl or whatever with the found items per list.

    ;=-=-=-=-=-= Example on how to remove them =-=-=-=-=-=

    ;== Lump all the mode-types to unset together
    var %modes = $+($str(b,$numtok(%ExpungeBans,32)),$str(e,$numtok(%ExpungeExcepts,32)),$str(I,$numtok(%ExpungeInvites,32)),$str(q,$numtok(%ExpungeQuiets,32)))

    ;== Lump all the masks to unset together
    var %masks = %ExpungeBans %ExpungeExcepts %ExpungeInvites %ExpungeQuiets

    ;== IF we have anything out of all 4 combined lists...
    if (%modes) {
      ;== Total is the CEILING of number of modes to perform / modesplit (think rounded up, remove the decimal/fraction) which gives us the ENTIRE count of times to iterate to clear the lists.
      ; for example, if modespl is 6 and we have 11 to unset, 11/6 ~= 1.8, we can't do a fraction of an iteration, so round up to 2. 1st iteration unsets the 1st 6, 2nd iteration unsets the remaining 5.
      var %x = 0 , %total = $ceil($calc($len(%modes) / $modespl)) , %beyond = $modespl + 1
      while (%x < %total) {
        inc %x
        ;== Unset the first few up to $modespl
        mode %chan - $+ $left(%modes,$modespl) $gettok(%masks,1- $+ $modespl,32)

        ;== Trim the lists by grabbing the remainder BEYOND what we just unset. We'll eventually have none.
        var %modes = $mid(%modes,%beyond) , %masks = $gettok(%masks,%beyond $+ -,32)
      }
    }
  }
}

Debug info:
Note: In multiple rooms, some not OP, some chan central already opened thus lists cached, #e was purposefully NOT cached to show it working
Code
<- PING :hybrid8.debian.local
-> hybrid8.debian.local PONG :hybrid8.debian.local
-> hybrid8.debian.local MODE #a -b *!*@*.foo
<- :TalWin!TalWin@192.168.0.3 MODE #a -b *!*@*.foo
-> hybrid8.debian.local MODE #e +beI
<- :hybrid8.debian.local 367 TalWin #e *!*@*.st TalWin!TalWin@192.168.0.3 1737058530
<- :hybrid8.debian.local 368 TalWin #e :End of Channel Ban List
<- :hybrid8.debian.local 348 TalWin #e *!*@*.com TalWin!TalWin@192.168.0.3 1737058530
<- :hybrid8.debian.local 349 TalWin #e :End of Channel Exception List
<- :hybrid8.debian.local 347 TalWin #e :End of Channel Invite List
-> hybrid8.debian.local MODE #e -be *!*@*.st *!*@*.com
<- :TalWin!TalWin@192.168.0.3 MODE #e -be *!*@*.st *!*@*.com

Output info:
Code
(status) *** Bans on: #a to remove: *!*@*.foo
(chan) * TalWin sets mode: -b *!*@*.foo
(status) *** Bans on: #e to remove: *!*@*.st
(status) *** Excepts on: #e to remove: *!*@*.com
(chan) * TalWin sets mode: -be *!*@*.st *!*@*.com


Link Copied to Clipboard