Disregarding the current $time, here we go again (replace the lengthy recent code with this one) smile

Code:
; text event: add IPs announced in channel #admin to an ini-file
on $*:text:/^(\S+) \(ID\W\d+\)'s Ip is ((\d{1,3}\.){3}\d{1,3})\.$/:#admin: {
  var %ini = $qt($shortfn($mircdirini\ips.ini)), %name = $replace($regml(1),[,$chr(40),],$chr(41))
  ; remove existing entry of that user and that ip
  if ($ini(%ini,%name)) { 
    var %n = 1
    while ($ini(%ini,%name,%n)) {
      if ($readini(%ini,%name,$v1) == $regml(2)) {
        remini -n %ini %name $ini(%ini,%name,%n) 
        break
      }
      inc %n
    }
  }
  ; and readd (updating the "timestamp") or simply add the data to to the ini
  writeini -n %ini %name $ctime $regml(2)
}



; trigger in chan #CnR|LV  to scan the database for ips (!ip <Name> [full]) or names (!ip <IP> [full]) 
on *:text:!ip*:#CnR|LV: {
  var %ini = $qt($shortfn($mircdirini\ips.ini)), %name = $replace($2,[,$chr(40),],$chr(41))
  var %reg = /^(?:\d{1,3}\.){3}\d{1,3}$/, %isIP = $iif($regex(%name,%reg),$true,$false)
  ; no match / error outputs
  if (!$2) {
    msg $chan No nickname/IP given. Use !ip <name> to get matching IPs, $&
    or !ip <IP> to get matching names. You can use "full" as second parameter.
  }
  elseif (!$ini(%ini,0)) { msg $chan IP-database is empty. }

  ; scan for name matches
  elseif (!%isIP) {
    if (!$ini(%ini,%name,0)) { msg $chan No entry for Name $qt($2) found. }
    ; loop matches for player name
    else {
      var %t = $ini(%ini,%name,0), %ips = $+($chr(31),IPs used by $2,$chr(15),:)
      while ((%t > 0) && ($ini(%ini,%name,%t))) {
        var %stamp = $v1, %ip = $readini(%ini,%name,%stamp)
        var %ips = %ips $iif(($3 == full),$+($chr(2),%ip,$chr(2)) $asctime(%stamp,(dd.mm.yy, HH:nn)),%ip) 
        ; output of matches
        if ($len(%ips) > 300) {
          msg $chan $makestringIP(%ips)
          var %ips
        }
        dec %t
      }
      if (%ips) { msg $chan $makestringIP($v1) }
    }
  }

  ; scan for IP matches
  else {
    var %reg = $+(/^\[|,$replace(%name,.,\.),$/), %tempini = $qt($shortfn($mircdirini\ipsTEMP.ini))
    ; filter the ini to a temporary ini, removing everything that's no ini topic or IP match
    filter -ffcg %ini %tempini %reg
    ; replace the matched IP in the data part of ini items with the player name (ini topic)
    var %n = 1
    while ($ini(%tempini,%n)) {
      var %topic = $v1
      if ($ini(%tempini,%topic,1)) { writeini -n %tempini %topic $v1 %topic }
      inc %n
    }
    ; filter tempini to remove ini topics (no longer needed), sort it (get timestamps in order)
    filter -ffcgxteu 1 61 %tempini %tempini ^\[
    ; no matches (no lines left)
    if (!$read(%tempini,1)) { msg $chan No entry for IP %name found. }
    ; loop and output the filtered matches 
    else {
      var %n = 1, %names = $+($chr(31),Names used on IP %name,$chr(15),:)
      while ($read(%tempini,%n)) {
        var %stamp = $gettok($v1,1,61), %player = $replace($gettok($v1,2,61),$chr(40),[,$chr(41),])
        var %names = %names $iif(($3 == full),$+($chr(2),%player,$chr(2)) $asctime(%stamp,(dd.mm.yy, HH:nn)),%player) 
        if ($len(%names) > 300) {
          msg $chan $makestringN(%names)
          var %names
        }
        inc %n
      }
      if (%names) { msg $chan $makestringN(%names) }
      .remove %tempini
    }
  }
}

; text formatting routines (output of !ip)
alias -l makestringIP { return $regsubex($1-,/(?<=\d\51|\d)\s/g,$+($chr(32),-,$chr(32))) }
alias -l makestringN { return $regsubex($1-,/(?<=\d\51)\s/g,$+($chr(32),-,$chr(32))) }



; text trigger for database cleanup: !cleanips <deadline>.
; (restricted to opped users at #CnR|LV) 
on @*:text:!cleanips*:#CnR|LV: { 
  if (($2 !isnum) && ($duration($2-) > 0)) {
    var %ini = $qt($shortfn($mircdirini\ips.ini))
    msg $chan There are currently $ini(%ini,0) players in the database. $&
      Start removing all IPs older than $duration($v1) ...
    set -e %ips.c.duration $v1
    set -e %ips.c.kept 0
    set -e %ips.c.removed 0
    ; init the cleaning (filter through an alias)
    if ($window(@ips.c)) { window -c @ips.c }
    window -h @ips.c
    filter -fk %ini clean.ips
    filter -wfc @ips.c %ini
    window -c @ips.c
    ; remove "dead" nick topics in the ini as well
    var %n = 1
    while ($ini(%ini,%n)) {
      var %name = $v1
      if (!$ini(%ini,%name,1)) { writeini -n %ini %name x y | remini -n %ini %name }
      inc %n
    }
    msg $chan ... Done. IPs kept: %ips.c.kept • IPs removed: %ips.c.removed • $&
      Players remaining in database: $ini(%ini,0) $+ .
    unset %ips.c.*
  }
  else {
    msg $chan Syntax is: !cleanips <deadline> 
    msg $chan e.g. "!cleanips 3d" will remove all entries older than 3 days; $&
      "!cleanips 2 weeks 3 hrs"
  }
}

; ip cleaning routine (filter-alias for !cleanips)
alias -l clean.ips {
  if ($gettok($1,1,61) isnum) { 
    if ($v1 >= $calc($ctime - %ips.c.duration)) { aline @ips.c $1- | inc %ips.c.kept }
    else { inc %ips.c.removed }
  }
  elseif ($1) { aline @ips.c $1- }
}


According to my tests it's working now as expected. Note that I was testing in a single channel (changing the #channels in the on text definition), but this shouldn't be an issue. And note that I act like the "bot" (the one with the script), while I use [Bot] to trigger the inputs :-)

[&Bot] •• !ip test
<~Horstl> IP-database is empty.

now I was first adding some IPs (10) and nicks (6)

[&Bot] •• Testnick (ID:123)'s Ip is 123.123.123.1.
[&Bot] •• Testnick (ID:123)'s Ip is 123.123.123.2.
[&Bot] •• {weird}|nick[x] (ID:77)'s Ip is 77.77.77.7.
[&Bot] •• Testnick (ID:123)'s Ip is 321.321.321.3.
[&Bot] •• {weird}|nick[x] (ID:77)'s Ip is 88.88.88.8.
[&Bot] •• XYZ (ID:5)'s Ip is 2.2.2.2.
[&Bot] •• {weird}|nick[x] (ID:77)'s Ip is 99.99.99.9.
[&Bot] •• Faker (ID:10)'s Ip is 321.321.321.3.
[&Bot] •• Faker2 (ID:11)'s Ip is 88.88.88.8.
[&Bot] •• Faker3 (ID:99)'s Ip is 321.321.321.3.

And started the testing...

<~Horstl> !ip testnick
[&Bot] •• !ip testnick
<~Horstl> IPs used by testnick: 321.321.321.3 - 123.123.123.2 - 123.123.123.1
[&Bot] •• !ip {weird}|nick[x]
<~Horstl> IPs used by {weird}|nick[x]: 99.99.99.9 - 88.88.88.8 - 77.77.77.7
[&Bot] •• !ip {weird}|nick[x] full
<~Horstl> IPs used by {weird}|nick[x]: 99.99.99.9 (02.11.08, 02:58) - 88.88.88.8 (02.11.08, 02:57) - 77.77.77.7 (02.11.08, 02:57)
[&Bot] •• !ip 88.88.88.8
<~Horstl> Names used on IP 88.88.88.8: Faker2 {weird}|nick[x]
[&Bot] •• !ip 88.88.88.8 full
<~Horstl> Names used on IP 88.88.88.8: Faker2 (02.11.08, 02:59) - {weird}|nick[x] (02.11.08, 02:57)
[&Bot] •• !ip 5.5.5.5
<~Horstl> No entry for IP 5.5.5.5 found.
[&Bot] •• !ip
<~Horstl> No nickname/IP given. Use !ip <name> to get matching IPs, or !ip <IP> to get matching names. You can use "full" as second parameter.
[&Bot] •• !ip Abc
<~Horstl> No entry for Name "Abc" found.
[&Bot] •• !ip Faker
<~Horstl> IPs used by Faker: 321.321.321.3
[&Bot] •• !ip Faker2
<~Horstl> IPs used by Faker2: 88.88.88.8
[&Bot] •• !cleanips 3hrs
<~Horstl> There are currently 6 players in the database. Start removing all IPs older than 3hrs ...
<~Horstl> ... Done. IPs kept: 10 • IPs removed: 0 • Players remaining in database: 6.
[&Bot] •• !cleanips 5mins
<~Horstl> There are currently 6 players in the database. Start removing all IPs older than 5mins ...
<~Horstl> ... Done. IPs kept: 5 • IPs removed: 5 • Players remaining in database: 5.

The only -minor- issue I found is the "players removed in database" info showing a "wrong" value due to strange /remini behaviour (It the ini topic holds no items, /remini refuses to remove the topic - I'm thus adding a dummy value in the cleaning procedure and /remove the topic right after, but sometimes this is failing, too). Repetitive cleaning will show the right count.