mIRC Home    About    Download    Register    News    Help

Print Thread
#273426 15/05/25 12:45 PM
Joined: Nov 2021
Posts: 154
Simo Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Nov 2021
Posts: 154
greetingz i have this netsplit check and wanted to have it check check on join the stored hosts on netsplit when they rejoin and ignore them not sure how to loop throu the hash table items to check for it on join tho.

Here is what i have so far:

Code

On *:Join:#:{
   if (stored ip on netsplit is detected)  { halt } 
}
 
 ON !^*:QUIT: {
  var %netsplit2 1
  while ($comchan($nick,%netsplit2)) {
    var %netsplitchan $v1
   if (*.* *.*  iswm $1-2) && !$3) {  .hadd -mu1800 eXp NetsplitStored. $+ %netsplitchan $+ .host $addtok($hget(eXp,FLoODPro. $+ %netsplitchan $+  .address),$address($nick,2),32) }
  if (*.* *.*  iswm $1-2) && !$3 && $eval($+(%,Netsplit-Detected.,$network),2) == $null) {
      set -z $+(%,Netsplit-Detected.,$network)  20
    }
    inc %netsplit2
  }
  halt
}



Joined: Aug 2013
Posts: 87
I
Babel fish
Online
Babel fish
I
Joined: Aug 2013
Posts: 87
Hello - I apologize in advance for the rather lengthy post, but before anything, there are three things I want to address. You can skip to the bottom if you just want an updated script, but I really hope you can take the time to read through this as I believe it will be quite informative and helpful. I've underlined key points to try to make them stand out:

First, I'm going to make a quick assumption:

I take it that the FLoODPro. $+ %netsplitchan $+ .address item being referenced within the /hadd command of the first if statement of the on QUIT event is a leftover "working draft" name that was actually meant to be the same item as the one being created/overwritten by the /hadd in the first place - (i.e., NetsplitStored. $+ %netsplitchan $+ .host), and is never created anywhere via external means. This assumption, whether true or not, won't really matter for the rest of my post, but for educational purposes, I think it's worth pointing out that if it is true, $hget(eXp,FLoODPro. $+ %netsplitchan $+ .address) will return $null every time, and as a consequence, the NetsplitStored. $+ %netsplitchan $+ .host item will only ever hold one address, rather than a space-separated list of addresses as you probably intended.

Second, I feel it's important to note that the parentheses around both of the if statements' condition groups in the on QUIT event are mismatched - you've closed them after the *.* *.* iswm $1-2 sub-condition in both cases, and then attempted to again at the end of the group without ever having reopened them.

This will be practically unnoticeable at the first if statement: mIRC's lax requirements regarding parentheses around conditions mean that no syntax error will be raised to complain about the lack of an opening "(" parenthesis to match the closing ")" parenthesis, and the fact that most text can be appended directly to the end of the $N identifiers without the use of the $+ concatenator means that mIRC will interpret the $3) either as:
  1. whatever the value of $3 is with a ")" character tacked on the end, or
  2. $null if it has no value,

and then determine whether or not the end result of that is $null, $false, or 0 via the ! operator.

The same cannot be said of the second if statement, however, and the unmatched/unopened ")" parenthesis can and should cause the script to fail because mIRC will attempt to evaluate $null) as an identifier, which is (hopefully) nonexistent. If the Identifier Warning option is disabled in the script editor's Options menu, it, and any other non-existent identifiers, will be interpreted as $null and the script will appear to work. However, if that option is instead enabled (which I strongly suggest it be in order to promote more carefully written code and highlight and prevent potential hard-to-detect bugs), mIRC will instead raise an error (specifically, "No such identifier: $null)" in this case) after either:
  1. jumping to the first available :error label in the call stack if one were present, (which of course there isn't, but that's beside the point), then executing any error handling code there, or
  2. halting the script outright.

Again, I would strongly urge you, for the reasons stated above, to enable the Identifier Warning option in your scripts editor if you haven't already. (Unfortunately, it is disabled by default.)

One last thing to keep in mind in regards to that second if statement is that its usage and placement are unideal. The first two sub-conditions, i.e., *.* *.* iswm $1-2 and !$3 are obviously redundant given how those same conditions are already checked in the first if statement, so you could at the very least achieve the same results by simply performing the variable existence check within that if statement's block:
Code
if (*.* *.* iswm $1-2) && (!$3) {
  ; add item to hash table
  if ($eval($+(%,Netsplit-Detected.,$network),2) == $null) {
    set -z $+(%,Netsplit-Detected.,$network) 20
  }
}
But better yet, the /set and /var commands both contain an i switch that will ensure that a variable only gets created and initialized if it doesn't already exist, so that additional if statement could be omitted entirely:
(On a side note, mIRC will not attempt to evaluate a variable while it's being created via the /set and /var commands, and giving one a dynamic name during that time is straightforward and doesn't require the kinds of workarounds needed when referencing them later on.)
Code
if (*.* *.* iswm $1-2) && (!$3) {
  ; add item to hash table
  set -iz $+( %Netsplit-Detected. , $network ) 20
}
Note that this is neither a shorthand for, nor exact replacement of, the previous method. The i switch works by checking for the existence of a variable and preventing mIRC from assigning a new value to one that already does exist, even if its value is $null. For your particular use case here, this should be perfectly suitable since the variable will get unset/deleted once it reaches 0, but there might be other cases where you may need or prefer to use the other method; it depends.

I also am a bit curious what the purpose of this variable is in the first place; it seems like it's meant to serve as a timer of sorts, but it's not used anywhere in your script currently. Are you using it elsewhere already or have plans for it in this script later on?

Anyway, third and finally, your current approach would store lists of addresses within hash table items named after the channels you and the users with those addresses occupy in common, and this in all likelihood would probably be fine most of the time, especially if you only ever find yourself in fairly small channels. However, if you do happen to be in a larger channel, say, with a few hundred members inside, then this approach could prove to be problematic because the length of the address list could exceed mIRC's large line length limit (as given by $maxlenl plus a little more), causing the script to fail when adding/updating a hash table item. For this reason almost entirely, I would suggest doing the reverse and store lists of channels within hash table items whose names are based on users' addresses instead. That way, it's very unlikely (maybe even impossible) that you would ever come anywhere near that limit. You may also want to consider naming and dedicating the table itself to netsplit-affected user storage for a given network, rather than using an all-purpose table name and encoding that information in the

So now, with all that said, let's get back to the original question.

The easiest way to determine whether or not a person is rejoining a channel after being part of a netsplit using your script would be to use $istok() in conjunction with the relevant hash table item's value; exactly what you would look for, of course, depends on whether or not you decide to take my suggestion to store lists of channels in hash tables named after users' addresses rather than the reverse.

If you don't implement my suggestion and keep your hash table structured the way you have it, then, as long as you modify the /hadd in your on QUIT event to reference the same item in the $hget() as the one being created or updated (i.e., NetsplitStored. $+ %netsplitchan $+ .host), and fix the parentheses for your if statements' condition groups, you should just have to check, in your on JOIN event:
Code
if ($istok( $hget( eXp , $+( NetsplitStored. , # , .host ) ) , $wildsite , 32 )) {
(Note that $wildsite is equivalent to $address( $nick , 2 ).)

If, however, you do take my suggestion to store lists of channels in items named after users' addresses instead, the idea would essentially be the same, except that you would check if the channel is a token in the item rather than the $wildsite.

Here's how I would write the script, including the recommendations I've provided above:
Code
alias -l comchanlist {
  !var %placeholder = $str( - $+ $chr(32) , $comchan( $1 , 0 ) )

  ; Note: []s (evaluation-prioritizing brackets) are needed around
  ; the $1 below because the meaning and values of most of the $N
  ; identifiers is overridden in $regsubex's subsitition parameter.
  ;
  !return $regsubex( %placeholder , /-/g , $comchan( [ $1 ] , \n ) )
}

alias -l netsplit_users {
  !return $+( eXp_ , $network , _Netsplit_Users )
}

; -----------------------------------------------------------------------------

on ^!*:JOIN:#: {

  ; Note: $wildsite is equivalent to $address( $nick , 2 )
  ;
  !if ($istok( $hget( $netsplit_users , $wildsite ) , # , 32 )) {
    !halt
  }
}

on ^!*:QUIT: {

  ; Note: this wildcard matching technique is not exactly robust,
  ; but it should work well enough for this particular situation.
  ;
  !if ($0 == 2) && (*.& *.& iswm $1-) {
    !hadd -mu1800 $netsplit_users $wildsite $comchanlist( $nick )

    ; Note: I don't know what the purpose of this variable is,
    ; but I've included it, regardless, in case you need it for something.
    ;
    !set -iz $+( %Netsplit-Detected. , $network ) 20
  }

  ; Do you really intend to halt ALL pre-processed QUIT events here,
  ; or just the ones that are triggered by netsplit-affected users?
  ; (In other words, should this actually be scoped to the if statement above?)
  ; 
  !halt
}
The ! prefixes in front of the (built-in) commands help to preserve the integrity of the script by ensuring that mIRC's versions of those commands get called in the event that you, for some reason, ever decide to override them with an alias or happen to load a script that does so. This prefix is not actually necessary before certain commands or keywords like if and /var, as these cannot be overridden, but I like to include it in such cases, anyway, for visual consistency.

This script also avoids an unnecessary loop by taking advantage of a combination of $regsubex() and $str() in the comchanlist alias. Essentially, the way this alias works is it first creates a series of space-separated - characters repeated "$comchan( $1 , 0 )" times, (where $1 is the nickname you want to check) using the $str() identifier, uses $regsubex() to substitute the Nth instance of those dashes with the Nth $comchan() value, and then returns the final result.

I hope this helps. Let me know if you have any other questions.

Joined: Aug 2013
Posts: 87
I
Babel fish
Online
Babel fish
I
Joined: Aug 2013
Posts: 87
Originally Posted by Iire
You may also want to consider naming and dedicating the table itself to netsplit-affected user storage for a given network, rather than using an all-purpose table name and encoding that information in the individual items' names.
...is how that sentence was meant to end. =r

Joined: Nov 2021
Posts: 154
Simo Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Nov 2021
Posts: 154
thanks lire i will work with that and go from there.


Link Copied to Clipboard