mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Feb 2010
Posts: 3
S
Self-satisified door
OP Offline
Self-satisified door
S
Joined: Feb 2010
Posts: 3
As the subject puts it, I'm having trouble with lines in text files when used in scripts.

Here's the scoop. I want to define lists in my text files. Each line with a specific thing on it.

Bad Words - Words that shouldn't be said by anyone. Sure you guys know what I mean here.
Bad Nicks - Nicknames with bad words in them.
NoKick - Nicknames that the bot should not be made to kick or ban under any circumstances. ((Owner, admins, etc))

The way I've been writing the script is like this.

on 500:TEXT:Kick *:?: {
if ($2 isin $read($mircdir\text\<filename>)) msg # I can't kick that person!
else /kick # $2
}

The thing is, it's not 100%. The more names, the less it hits. I know $read is doing it randomly, I need it for the entire list.

Is there a way to make the script glance at the list.txt and if any line matches, trigger the if condition?

Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
You can loop through every line (or put all bad words on one line, nicks on one line, etc) as long as their aren't too many words, then just read that one line using $read(filename.txt,line#), or using an ini file format, which would probably work better as long as your list of words/nicks isn't too large.

However, it would be more efficienct to use hash tables if you have a lot of words/nicks. Hash tables are easy to work with. Create the table (/hmake), load your saved list (if you've already saved a list) (/hload), then check using $hget() to see if it's on the list when you need to check something. You can also easily add new words/nicks (/hadd), or remove them (/hdel). Just be sure to save (/hsave) after making changes.


Invision Support
#Invision on irc.irchighway.net
Joined: Feb 2010
Posts: 3
S
Self-satisified door
OP Offline
Self-satisified door
S
Joined: Feb 2010
Posts: 3
I thought hash tables might work. But I have little experience with them. Well, none really.

How exactly would I write the $hget?

Joined: Feb 2009
Posts: 133
C
Vogon poet
Offline
Vogon poet
C
Joined: Feb 2009
Posts: 133
Code:
on 500:TEXT:*:?:{
  if ($strip($1) == kick) && ($2) && ($3) {
    if ($read($scriptdir\text\<filename>,w,$2)) msg $nick I can't kick $2 !
    elseif (($chan($3)) && ($2 ison $3)) kick $3 $2
  }
}


use: kick <nick> <channel>


WorldDMT
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
It depends on how you want to set it up. Either way, you'll need to loop it for bad words because you need to check everything in the line. For nicks, you can look it up with just:

Code:
  if ($hget(Nicks,$nick)) { do something }


For words, you'd need to do something like:

Code:
var %c = 1, %t = $hget(BadWords,0).item
while (%c <= %t) {
  if ($hget(Badwords,%c).item isin $1-) { do something and halt if needed }
  inc %c
}


To add something to it:

/hadd BadWords word fake_data
/hadd Nicks nick fake_data

You have to include data even if you're not using it, so you can put anything in place of fake_data... such as the number 1 or whatever. You're not using it, so it doesn't really matter. A single character takes less memory/space though, so that would be better than a word or whatever else.

Remember to have separate tables... one for bad words, one for nicks, etc. so they don't get mixed up. Alternatively, if you have few enough words/nicks so that you don't run into line too long errors, you can put them all into a single item and then you can use one hash table for everything (Badwords, nicks, etc). In that case,

/hadd MyHashTable BadWords word,word,word,word,word
/hadd MyHashTable Nicks nick,nick,nick,nick

This does, however, make adding/removing them more challenging.

As a note, you *could* use a binary hash table and then store all bad words on a single line (item = BadWords, data = all your bad words). This may even work more efficiently, but it takes a bit more work to set up and you can't read the saved hash table data visually. If you do a binary hash table, since you can have all of the words on one item, you can just use one table that has items BadWords, Nicks, etc... basiccaly the same as if you have few words/nicks as mentioned above. As a note with binary tables, you'll write and read the data differently.


Invision Support
#Invision on irc.irchighway.net
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
Btw, if you wanted to look for complete words and not partial matches, a good way would be to have each word be an item in the table and then look it up like this:

Note: add all punctuation to the $remove list... this prevents something like badword. from not matching because of the "."

Code:
tokenize 32 $remove($1,.,$chr(44),!,?)
var %c = 1, %t = $0
while (%c <= %t) {
  if ($hget(BadWords,$eval($+($,%c),2)) { do something and halt if needed }
  inc %c
}


Note: for this part ($,%c) you may have to replace $ with the $chr() value, which I can't remember off the top of my head. It would then look like ($chr(##),%c) where the ## is the $chr() value of $.

Basically, this method will look for whole words instead of all matches, which prevents something like "bass" from being treated as a bad word.

No matter how you do it, people can get around it once they figure out how it's being handled. But it's usually not hard to notice the people doing things to get around it and you can ban them or whatever you want manually.


Invision Support
#Invision on irc.irchighway.net
Joined: Feb 2010
Posts: 3
S
Self-satisified door
OP Offline
Self-satisified door
S
Joined: Feb 2010
Posts: 3
I can't make the hash tables work. Something is wrong. I think I'm gonna have to stick with the words in the text file. I know nothing about hash tables, and not sure why but when I tried the above for it, it locked up mIRC when I used the bad word in channel (monkey in this case) and ultimately had to use the task manager to force it closed.

Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
Would have to see exactly what you used for the script. Most likely you didn't have the WHILE loop set up quite right so it just kept looping.


Invision Support
#Invision on irc.irchighway.net
Joined: Jul 2007
Posts: 1,129
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
Quote:
Bad Words - Words that shouldn't be said by anyone. Sure you guys know what I mean here.
Bad Nicks - Nicknames with bad words in them.
NoKick - Nicknames that the bot should not be made to kick or ban under any circumstances. ((Owner, admins, etc))

Code:
on 500:text:$($+($strip(kick),*)):*: {
  if (!$nick($comchan($nick,1),$2,@%&~)) && ($me isop $comchan($nick,1)) && ($2 ison $ifmatch2) {
    $iif($read($scriptdir\text\<filename>,w,$2),.msg $nick I can't kick $2 $+ !,kick $comchan($nick,1) $2)
  }
}
on *:nick:if ($me isop $comchan($me,1)) cuss
on *:text:*:*:if ($me isop $comchan($me,1)) cuss $strip($1-)
on *:action:*:*:if ($me isop $comchan($me,1)) cuss $strip($1-)
on *:notice:*:*:if ($me isop $comchan($me,1)) cuss $strip($1-)
alias -l cuss {
  var %a = badword1|badword2|badword3|badword4
  var %b = badnick1|badnick2|badnick3|badnick4
  var %n = $numtok(%a,32)
  while (%n) {
    if ($istok($1-,$gettok(%a,%n,124),32)) { kick $comchan($nick,1) $nick No cussing! }
    dec %n
  }
  if ($regex($newnick,/( $+ %b $+ )/)) { kick $comchan($newnick,1) $newnick No bad nick allowed! }
}
Replace badword1 etc..and badnick1 etc..with the ones you want to watch out for. (a pipe (|) is to be placed between each added)

You can also make the variable a and b to search from the text file too...if you want.

Joined: Feb 2009
Posts: 133
C
Vogon poet
Offline
Vogon poet
C
Joined: Feb 2009
Posts: 133
$nick support only PREFIX ohv and/or @%+

about your alias CUSS better to add $event to avoid the loop without the need for it

Code:
alias -l cuss {
  var %a = badword1|badword2|badword3|badword4
  var %b = badnick1|badnick2|badnick3|badnick4
  var %n = $numtok(%a,32)
  if (($event == nick) && ($regex($newnick,/( $+ %b $+ )/))) kick $comchan($newnick,1) $newnick No bad nick allowed!
  elseif $istok(text.action.notice,$event,46) {
    while (%n) {
      if ($istok($1-,$gettok(%a,%n,124),32)) kick $comchan($nick,1) $nick No cussing!
      dec %n
    }
  }
}


u cant use $comchan bcz if they have 3 comchans and he kick him from the third the code will kick him from the first that's too bad !! and u have to add ON JOIN event for bad nicks




WorldDMT
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
To point out, these script methods also are limited in number of words/nicks unless you use binary or have many variables that you want to check.


Invision Support
#Invision on irc.irchighway.net
Joined: Jul 2007
Posts: 1,129
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
Thanks chacha for the pointer. I didn't put much thought into the matter of $comchan in the first place. It completely crossed my mind about the use of $event too.


Link Copied to Clipboard