Seb icon

RegFix.mrc

Seb | PRO | 08/10/26 12:43:59 AM UTC | 0 ⭐ | 11330 👁️ | Never ⏰ | []
mIRC |

11.55 KB

|

None

|

0 👍

/

0 👎

;; ============================================================================
;;  RegFix  -  regular-voicer for AdiIRC / mIRC
;;  Auto +v's channel regulars on join, scored by DISTINCT DAYS SEEN.
;;  Multi-channel. Per-channel right-click enable/disable. Per-channel logging.
;;  Disabled = keeps scoring + logging, just stops auto-voicing.
;;  Data: <mircdir>\RegFix\   (one .hsh file per channel + regfix.ini config)
;;
;;  Quick start:
;;    1) Load this script.
;;    2) Right-click in a channel  -> RegFix -> "Start tracking here".
;;    3) Right-click               -> RegFix -> "Set log channel..."
;;    4) (optional) set the voice threshold; default is 7 distinct days.
;; ============================================================================
 
;; ----- storage / config helpers --------------------------------------------
 
alias -l rf.dir {
  var %d = $+($mircdir,RegFix\)
  if (!$isdir(%d)) mkdir %d
  return %d
}
alias -l rf.cfg return $+($rf.dir,regfix.ini)
alias -l rf.safe return $regsubex($1,/[^a-z0-9]/gi,$null)
alias -l rf.datafile return $+($rf.dir,data-,$rf.safe($1),.hsh)
alias -l rf.table return $+(rf.tbl.,$rf.safe($1))
 
alias -l rf.open {
  var %t = $rf.table($1)
  if (!$hget(%t)) {
    hmake %t 100
    if ($isfile($rf.datafile($1))) hload %t $rf.datafile($1)
  }
  return %t
}
alias -l rf.saveone {
  if ($hget($rf.table($1))) hsave $rf.table($1) $rf.datafile($1)
}
alias -l rf.saveall {
  var %i = 1
  while (%i <= $ini($rf.cfg,0)) {
    rf.saveone $ini($rf.cfg,%i)
    inc %i
  }
}
 
;; ----- per-channel config getters ------------------------------------------
 
alias -l rf.tracked return $iif($readini($rf.cfg,n,$1,tracked) == 1,1,0)
alias -l rf.enabled return $iif($readini($rf.cfg,n,$1,enabled) == 1,1,0)
alias -l rf.logchan return $readini($rf.cfg,n,$1,logchan)
alias -l rf.threshold {
  var %v = $readini($rf.cfg,n,$1,threshold)
  return $iif(%v isnum,%v,7)
}
 
;; ----- record field helpers (tab-delimited) --------------------------------
;;  1 nick | 2 ident@host | 3 ip(or -) | 4 days | 5 firstday | 6 lastday
;;  7 lastseen(ctime) | 8 flag(normal/force/never)
 
alias -l rf.fld return $gettok($1,$2,9)
alias -l rf.setfld return $puttok($1,$3,$2,9)
alias -l rf.mkrec return $+($1,$chr(9),$2,$chr(9),$3,$chr(9),$4,$chr(9),$5,$chr(9),$6,$chr(9),$7,$chr(9),$8)
alias -l rf.today return $int($calc($ctime / 86400))
 
alias -l rf.idh {
  var %u = $ial($1).user, %h = $ial($1).host
  if (%h != $null) return $+(%u,@,%h)
  var %a = $address($1,6)
  if (%a) return $gettok(%a,2,33)
  return $null
}
alias -l rf.isip {
  if ($regex($1,/^(\d{1,3}\.){3}\d{1,3}$/)) return $true
  if ($regex($1,/^[0-9a-f:]+:[0-9a-f:]+$/i)) return $true
  return $false
}
alias -l rf.nextid {
  var %t = $rf.open($1), %id = $hget(%t,nextid)
  if (%id == $null) %id = 1
  hadd %t nextid $calc(%id + 1)
  return %id
}
 
;; ----- find an existing record by nick OR host OR ip (exact) ----------------
 
alias -l rf.find {
  ; $1 chan  $2 nick  $3 ident@host  $4 ip(optional)
  var %t = $rf.open($1), %i = 1, %tot = $hget(%t,0).item
  while (%i <= %tot) {
    var %k = $hget(%t,%i).item
    if (%k != nextid) {
      var %rec = $hget(%t,%k)
      if (($2 != $null) && ($rf.fld(%rec,1) == $2)) return %k
      if (($3 != $null) && ($rf.fld(%rec,2) == $3)) return %k
      if (($4 != $null) && ($rf.fld(%rec,3) != -) && ($rf.fld(%rec,3) == $4)) return %k
    }
    inc %i
  }
  return $null
}
 
;; ----- credit a day (create or update). Returns record id ------------------
 
alias -l rf.credit {
  ; $1 chan  $2 nick  $3 ident@host  $4 ip(optional)
  if (!$rf.tracked($1)) return
  var %t = $rf.open($1), %ip = $iif($4 != $null,$4,-)
  var %id = $rf.find($1,$2,$3,$iif(%ip != -,%ip,$null)), %today = $rf.today
  if (%id == $null) {
    %id = $rf.nextid($1)
    hadd %t %id $rf.mkrec($2,$3,%ip,1,%today,%today,$ctime,normal)
    rf.saveone $1
    rf.log $1 New entry: $2 ( $+ $3 $+ ) - day 1
    return %id
  }
  var %rec = $hget(%t,%id)
  %rec = $rf.setfld(%rec,1,$2)
  %rec = $rf.setfld(%rec,2,$3)
  if (%ip != -) %rec = $rf.setfld(%rec,3,%ip)
  %rec = $rf.setfld(%rec,7,$ctime)
  if (%today > $rf.fld(%rec,6)) {
    var %days = $calc($rf.fld(%rec,4) + 1)
    %rec = $rf.setfld(%rec,4,%days)
    %rec = $rf.setfld(%rec,6,%today)
    hadd %t %id %rec
    rf.saveone $1
    if (%days == $rf.threshold($1)) rf.log $1 $2 reached %days days - now a regular (threshold $rf.threshold($1))
  }
  else hadd %t %id %rec
  return %id
}
 
;; ----- logging to the per-channel back-channel ------------------------------
 
alias -l rf.log {
  var %lc = $rf.logchan($1)
  if (%lc == $null) return
  if ($me ison %lc) msg %lc [RegFix $1] $2-
  else echo -a [RegFix $1] (log %lc offline) $2-
}
 
;; ----- events ---------------------------------------------------------------
 
on *:JOIN:#: {
  if ($nick == $me) return
  if (!$rf.tracked($chan)) return
  var %idh = $rf.idh($nick)
  if (%idh == $null) return
  var %host = $gettok(%idh,2,64)
  var %ip = $iif($rf.isip(%host),%host,$null)
  var %id = $rf.credit($chan,$nick,%idh,%ip)
  var %rec = $hget($rf.table($chan),%id), %flag = $rf.fld(%rec,8)
  if (%flag == never) return
  if (!$rf.enabled($chan)) return
  if (!$me isop $chan) return
  if (%flag == force) || ($rf.fld(%rec,4) >= $rf.threshold($chan)) {
    if ($left($nick($chan,$nick).pnick,1) !isin $+(~,&,@,%,+)) {
      .timer 1 1 mode $chan +v $nick
      rf.log $chan Voiced $nick ( $+ $rf.fld(%rec,4) days, flag %flag $+ )
    }
  }
}
 
;; periodic sweep: credits everyone currently present (catches users who were
;; here before the script loaded, and midnight roll-overs). Scoring only.
alias -l rf.scan {
  var %ci = 1
  while (%ci <= $chan(0)) {
    var %c = $chan(%ci)
    if ($rf.tracked(%c)) {
      var %ni = 1
      while (%ni <= $nick(%c,0)) {
        var %n = $nick(%c,%ni), %idh = $rf.idh(%n)
        if (%idh != $null) {
          var %host = $gettok(%idh,2,64)
          rf.credit %c %n %idh $iif($rf.isip(%host),%host,$null)
        }
        inc %ni
      }
    }
    inc %ci
  }
}
alias -l rf.starttimer {
  .timerRegFix off
  .timerRegFix 0 1800 rf.scan
}
 
on *:START:rf.starttimer
on *:LOAD:{ rf.starttimer | echo -a [RegFix] Loaded. Right-click a channel -> RegFix -> Start tracking here. }
on *:UNLOAD:rf.saveall
on *:EXIT:rf.saveall
 
;; ----- actions used by the menus -------------------------------------------
 
alias -l rf.track {
  if ($2 == 1) {
    writeini $rf.cfg $1 tracked 1
    if ($readini($rf.cfg,n,$1,enabled) == $null) writeini $rf.cfg $1 enabled 1
    if ($readini($rf.cfg,n,$1,threshold) == $null) writeini $rf.cfg $1 threshold 7
    rf.open $1
    echo -a [RegFix] Now tracking $1 $+ . Set a log channel via the menu.
    rf.log $1 Tracking started by $me
  }
  else {
    writeini $rf.cfg $1 tracked 0
    echo -a [RegFix] Stopped tracking $1 (data kept).
    rf.log $1 Tracking stopped by $me
  }
}
alias -l rf.toggleenable {
  if ($rf.enabled($1)) {
    writeini $rf.cfg $1 enabled 0
    echo -a [RegFix] Auto-voice DISABLED for $1 (still scoring).
    rf.log $1 Auto-voice disabled by $me
  }
  else {
    writeini $rf.cfg $1 enabled 1
    echo -a [RegFix] Auto-voice ENABLED for $1 $+ .
    rf.log $1 Auto-voice enabled by $me
  }
}
alias -l rf.setlog {
  var %c = $input(Log / back-channel for $1 (include the #):,e,RegFix Setup)
  if (%c != $null) {
    writeini $rf.cfg $1 logchan %c
    echo -a [RegFix] Log channel for $1 set to %c
    rf.log $1 Log channel set to %c by $me
  }
}
alias -l rf.setthreshold {
  var %v = $input(Distinct days seen before auto-voicing in $1 :,e,RegFix Setup,$rf.threshold($1))
  if (%v isnum) {
    writeini $rf.cfg $1 threshold $int(%v)
    echo -a [RegFix] Voice threshold for $1 set to $int(%v) days.
    rf.log $1 Voice threshold set to $int(%v) by $me
  }
}
alias -l rf.showscore {
  var %idh = $rf.idh($2), %host = $gettok(%idh,2,64)
  var %id = $rf.find($1,$2,%idh,$iif($rf.isip(%host),%host,$null))
  if (%id == $null) { echo -a [RegFix] No record for $2 in $1 $+ . | return }
  var %rec = $hget($rf.table($1),%id)
  echo -a [RegFix] $2 in $1 : $rf.fld(%rec,4) days | flag: $rf.fld(%rec,8) | last seen: $asctime($rf.fld(%rec,7),mmm d HH:nn) | host: $rf.fld(%rec,2)
}
alias -l rf.remove {
  var %idh = $rf.idh($2), %host = $gettok(%idh,2,64)
  var %id = $rf.find($1,$2,%idh,$iif($rf.isip(%host),%host,$null))
  if (%id == $null) { echo -a [RegFix] No record for $2 in $1 $+ . | return }
  hdel $rf.table($1) %id
  rf.saveone $1
  echo -a [RegFix] Removed $2 from $1 scores.
  rf.log $1 Removed $2 from scores by $me
}
alias -l rf.setflag {
  ; $1 chan  $2 nick  $3 flag(normal/force/never)
  var %t = $rf.open($1), %idh = $rf.idh($2), %host = $gettok(%idh,2,64)
  var %id = $rf.find($1,$2,%idh,$iif($rf.isip(%host),%host,$null))
  if (%id == $null) {
    %id = $rf.nextid($1)
    var %today = $rf.today
    hadd %t %id $rf.mkrec($2,%idh,$iif($rf.isip(%host),%host,-),0,%today,0,$ctime,$3)
  }
  else hadd %t %id $rf.setfld($hget(%t,%id),8,$3)
  rf.saveone $1
  echo -a [RegFix] $2 flag set to $3 in $1 $+ .
  rf.log $1 $2 flag set to $3 by $me
}
alias -l rf.top {
  var %t = $rf.open($1), %i = 1, %tot = $hget(%t,0).item, %list
  while (%i <= %tot) {
    var %k = $hget(%t,%i).item
    if (%k != nextid) {
      var %rec = $hget(%t,%k)
      if (%list != $null) %list = %list $+ $chr(59)
      %list = %list $+ $rf.fld(%rec,4) $rf.fld(%rec,1) [ $+ $rf.fld(%rec,8) $+ ]
    }
    inc %i
  }
  %list = $sorttok(%list,59,nr)
  echo -a [RegFix] Top regulars in $1 (threshold $rf.threshold($1) days):
  var %j = 1
  while (%j <= 20) && (%j <= $numtok(%list,59)) {
    echo -a [RegFix]  $+ $chr(32) $gettok(%list,%j,59) days
    inc %j
  }
}
alias -l rf.purge {
  ; remove records whose lastseen is older than $2 days (force-flagged kept)
  var %t = $rf.open($1), %cut = $calc($ctime - ($2 * 86400)), %i = 1, %tot = $hget(%t,0).item, %kill
  while (%i <= %tot) {
    var %k = $hget(%t,%i).item
    if (%k != nextid) {
      var %rec = $hget(%t,%k)
      if (($rf.fld(%rec,7) < %cut) && ($rf.fld(%rec,8) != force)) %kill = $addtok(%kill,%k,59)
    }
    inc %i
  }
  var %j = 1
  while (%j <= $numtok(%kill,59)) { hdel %t $gettok(%kill,%j,59) | inc %j }
  rf.saveone $1
  echo -a [RegFix] Purged $numtok(%kill,59) entries (inactive > $2 d) in $1 $+ .
  if ($numtok(%kill,59) > 0) rf.log $1 Purged $numtok(%kill,59) inactive entries (> $2 d) by $me
}
 
;; ----- menus ----------------------------------------------------------------
 
menu channel {
  -
  RegFix
  .$iif(!$rf.tracked($chan),Start tracking here):rf.track $chan 1
  .$iif($rf.tracked($chan),$iif($rf.enabled($chan),$style(1)) Auto-voice regulars):rf.toggleenable $chan
  .$iif($rf.tracked($chan),Set log channel...):rf.setlog $chan
  .$iif($rf.tracked($chan),Set voice threshold...):rf.setthreshold $chan
  .$iif($rf.tracked($chan),Show top regulars):rf.top $chan
  .$iif($rf.tracked($chan),-)
  .$iif($rf.tracked($chan),Save scores now):rf.saveall
  .$iif($rf.tracked($chan),Purge inactive (90d+)):rf.purge $chan 90
  .$iif($rf.tracked($chan),Stop tracking (keep data)):rf.track $chan 0
}
 
menu nicklist {
  -
  RegFix
  .$iif($rf.tracked($chan),Score for $1):rf.showscore $chan $1
  .$iif($rf.tracked($chan),Voice now):mode $chan +v $1
  .$iif($rf.tracked($chan),Remove from scores):rf.remove $chan $1
  .$iif($rf.tracked($chan),-)
  .$iif($rf.tracked($chan),Force voice (always)):rf.setflag $chan $1 force
  .$iif($rf.tracked($chan),Never voice):rf.setflag $chan $1 never
  .$iif($rf.tracked($chan),Clear flag (normal)):rf.setflag $chan $1 normal
}
 

Comments