mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Jan 2023
Posts: 2
Z
zalea Offline OP
Bowl of petunias
OP Offline
Bowl of petunias
Z
Joined: Jan 2023
Posts: 2
on *:text:*Hello*:#: { .timer 1 $rand(2,5) msg $chan Hello there }

how to stop reply on second *Hello* ?

Joined: Jan 2012
Posts: 299
Fjord artisan
Offline
Fjord artisan
Joined: Jan 2012
Posts: 299
The easiest way - is to create a constant variable that will stop the autoresponder from firing again as long as this variable exists.
But it is also desirable that this variable be deleted after some time, so I suggest using the switch "-u300" (300 seconds), to set the time for auto deletion of the variable.

For example:
Code
on *:TEXT:*Hello*:#:{
  if (!%no_reply1) {
    .timerAUTOREPLY1 1 $rand(2,5) msg $chan $+($nick,$chr(44)) Hi dude!
    set -u300 %no_reply1 $true
  }
}

Ideally, this would be better done with hash tables instead of variables.


🌐 http://forum.epicnet.ru 📜 irc.epicnet.ru 6667 #Code | mIRC scripts, help, discuss, examples
Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
Whenever you have a timer or scid or /scon (and more) and unknown data, because of the double evaluation, you must use $unsafe to avoid injections

Here $chan could be used to evaluate identifiers via #$identifier.

Code
on *:TEXT:*Hello*:#:{
  if (!%no_reply1) {
    .timerAUTOREPLY 1 $rand(2,5) msg $unsafe($chan $nick $+ $chr(44) Hi dude!)
    set -u600 %no_reply1 $true
  }
}


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
Updating for 2 issues.

(A) This %no_reply1 handles the hello greeting for all channels, so if hello is said in 2 different channels within 600 seconds, your reply will not happen in that last channel

(B) The %no_reply1 variable exists as a temporary variable for 600 seconds, and then mIRC removes it. However, it's possible that sometime during that 600 seconds, mIRC could perform the occasional safety-save to disk of variables and settings. This can happen by using the /saveini command, and can even happen by simply going into the scripts editor. If that happens, then mIRC writes ALL the variables to disk, including these temporary variables.

If you then exit mIRC normally while this variable exists, mIRC writes the variables to disk as part of its EXIT cleanup, and at that time it does not write the temporary variable to disk.

However, if mIRC crashes or the computer itself crashes/reboots between that safety-save backup and when the 600 seconds period ends, the next time mIRC starts up, that %no_reply1 variable exists as a permanent variable that will never be unset, which means your script will never ever reply to anyone.

* *

There are several solutions:

1. To fix only the 2nd issue, create an ON START event, where you have an /unset command for all temporary variables used by all your scripts which are assuming these variable names will not exist without being temporary. Example:

Code
on *:START:{
  unset %no_reply1
}

2. You can have a separate variable for each channel by having the channelname be part of the variable name. For example %no_reply1#test %no_reply1#zalea etc. It's a little more complicated to create these compound variable names using $chan

So this solution will create your variables instead as item in a hashtable, where you can create temporary hashtable items that disappear after 600 seconds, and the syntax to create and access them is much simpler. The hashtable does not get saved to disk unless you specifically use the /hsave command, and does not get loaded up from disk without using the /hload command. And the /hsave command by default does not save the temporary items to disk unless you use a switch to override that.

This code also has a change where the variable contains the name of the network, so you can be in #channel1 and #channel2 at networks Network1 and Network2, and if someone says hello in all 4 channels near the same time, your script will reply to each channel, and each channel will have its own countdown.

Another change to make it work in several channels is that the name of the timer cannot be the same every time, or else someone's timer will replace an existing timer belonging to a different channel. This creates an item in the hashtable named 0increment that will ensure the timer name changes each time, and allows your script to be changed later so that you can say hello when someone queries you, and 0increment is not likely to be not a valid nick. Note that 0increment is not temporary, because we want this to never repeat the same number.

Code
ON *:TEXT:*Hello*:#:{
  if (!$hget(no_reply1,$+($network,$chan))) {
    hinc -m no_reply1 0increment
    .timerAUTOREPLY $+ $hget(no_reply1,0increment) 1 $rand(2,5) msg $unsafe($chan $nick $+ $chr(44) Hi dude!)
    hadd -mu600 no_reply1 $+($network,$chan) $true
  }
}

* *

Note that both the above scripts will reply to all channels, and some of them will find it annoying for you to answer hello every time someone says hello to anyone else, and this will easily get you banned. You can make the script behave only in a specific channel or in a specific list of channels by changing the :#: to instead list the channel/channels for this script. For example,

ON *:TEXT:*Hello*:#:
changes to

ON *:TEXT:*Hello*:#channel1:
or
ON *:TEXT:*Hello*:#channel1,#channel2:

If the script is limited to acting in only a specific list of channels, then the $unsafe is not needed. Though it's a good idea to get into the habit of using it when a timer contains text that someone else can control!

Joined: Dec 2002
Posts: 252
T
Fjord artisan
Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 252
Since this is throw-away data, there's no sense in having a special database for it, like hash/ini/text/global vars...

The simplest solution would be to take advantage of /ialmark. I assume for the lifespan a user remains within your ial you only wish to respond ONCE to a specific trigger, like hello. If it is indeed intended to only allow a response every 10 minutes like maroons example, uncomment the last line.

This also circumvents the issue about disk-writes maroon mentioned with using variables. This also addresses an unforseen problem with maroons hash-table example as it does not follow nick changes and would re-trigger if they consistantly change nicknames to ones not logged into the database. By using IAL, this is managed automatically for us!

Code
ON *:TEXT:*Hello*:#:{
  if (!$ialmark($nick,$+($chan,.greeted))) {
    .ialmark -n $nick $+($chan,.greeted) 1
    .timer 1 $rand(2,5) msg $unsafe($chan $nick $+ $chr(44) Hi dude!)

    ;== Uncomment below to make it trigger only once per nick within 600ms...
    ;$+(.timer,$chan,.,$nick) 1 600 .ialmark -rn $nick $+($chan,.greeted)
  }
}

Remember that an IAL entry persists as long as there are common rooms between you and the user. If you want this to re-trigger again if they rejoin from a part/kick and say "hello", you'd want to unset that mark on part/kick as well (in-case they're in more than one common channel, if not, it's un-necessary as it'll naturally get expunged)

You do not have to worry about a part/kick event to unset the mark if you've uncommented that timer (allowing it to always trigger as long as it hasn't been triggered previously by the same user within 10 mins)

Joined: Jan 2014
Posts: 107
M
Vogon poet
Offline
Vogon poet
M
Joined: Jan 2014
Posts: 107
Originally Posted by Talon
Since this is throw-away data, there's no sense in having a special database for it, like hash/ini/text/global vars...

The simplest solution would be to take advantage of /ialmark. I assume for the lifespan a user remains within your ial you only wish to respond ONCE to a specific trigger, like hello. If it is indeed intended to only allow a response every 10 minutes like maroons example, uncomment the last line.

This also circumvents the issue about disk-writes maroon mentioned with using variables. This also addresses an unforseen problem with maroons hash-table example as it does not follow nick changes and would re-trigger if they consistantly change nicknames to ones not logged into the database. By using IAL, this is managed automatically for us!

Code
ON *:TEXT:*Hello*:#:{
  if (!$ialmark($nick,$+($chan,.greeted))) {
    .ialmark -n $nick $+($chan,.greeted) 1
    .timer 1 $rand(2,5) msg $unsafe($chan $nick $+ $chr(44) Hi dude!)

    ;== Uncomment below to make it trigger only once per nick within 600ms...
    ;$+(.timer,$chan,.,$nick) 1 600 .ialmark -rn $nick $+($chan,.greeted)
  }
}

Remember that an IAL entry persists as long as there are common rooms between you and the user. If you want this to re-trigger again if they rejoin from a part/kick and say "hello", you'd want to unset that mark on part/kick as well (in-case they're in more than one common channel, if not, it's un-necessary as it'll naturally get expunged)

You do not have to worry about a part/kick event to unset the mark if you've uncommented that timer (allowing it to always trigger as long as it hasn't been triggered previously by the same user within 10 mins)

How would a person go about implementing this without it adding the persons $nick in the response? I tried editing the code and it breaks it completely when you remove $nick from line 4.

Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
.timer 1 $rand(2,5) msg $unsafe($chan Hi dude!)


#mircscripting @ irc.swiftirc.net == the best mIRC help channel

Link Copied to Clipboard