mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Dec 2007
Posts: 24
T
Tzar469 Offline OP
Ameglian cow
OP Offline
Ameglian cow
T
Joined: Dec 2007
Posts: 24
I have a bot that stores quotes in a file called quotes.txt. When a user types !qfind <text>, I want it to look through the quotes.txt and message quote with <text> . The code below works, but it only returns the first quote with the <text> and then stops. How would I make it search through the entire file and, if there are multiple quotes, message the line numbers of those quotes?

Code:
if ($1 == !quotefind) || ($1 == !qfind) {
    if (!$2) { msg $chan Insufficient parameters. Syntax: $1 <matchword> | return }
    if ($read(quotes.txt,nw,* $+ $2- $+ *)) {
      tokenize 92 $v1
      .msg $chan 04 $+ $chr(91) Quote $1 $chr(93) $+  $2
      .msg $chan 4Submitted by12: $3 4Rated12: $4
    }  
    else {
      .notice $nick $qt($2-) was not found in the quote database.
    }
  }

Joined: May 2007
Posts: 89
T
Babel fish
Offline
Babel fish
T
Joined: May 2007
Posts: 89
Not tested but it must/will function wink .

Code:
If ($1 == !quotefind) || ($1 == !qfind) {
  If (!$2) { .Msg $chan Insufficient parameters. Syntax: $1 <matchword> | Return }
  Var %l = $lines(quotes.txt) , %m = 1 , %n = 0
  While (%m <= %l) {
    If ($2- iswm $read(quotes.txt,%m)) {
      Inc %n | Tokenize 92 $v2
      .Timer 1 %n .Msg $chan 04 $+ $chr(91) Quote $1 $chr(93) $+  $2
      .Timer 1 %n .Msg $chan LineNumber: %m 4Submitted by12: $3 4Rated12: $4
    }
    Inc %m
  }  
  If (%n == 0) { .Notice $nick $qt($2-) was not found in the quote database. }
  Else { Echo -ast %n quotes were found matching $qt($2-) }
}


Cordialement

Edit: I knew I included the line number (%m) but because of some unknown bug, it was not showing here. I changed the disposition now hoping it displays correctly henceforth. Thanks Horstl ^^.

Last edited by TropNul; 05/12/07 06:09 AM.

tropnul
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
TropNul,
Quote:
(...) and, if there are multiple quotes, message the line numbers of those quotes?
wink

Code:
if ($1 == !quotefind) || ($1 == !qfind) {
  if (!$2) { msg $chan Insufficient parameters. Syntax: $1 <matchword> | return }

  ; setting variables for 1) the line to start reading at 2) the matching lines (which is empty first)
  var %nr = 1, %matches

  ; (loop): read the file starting at line nr. %nr
  while ($read(quotes.txt,nw,* $+ $2- $+ *,%nr)) {

    ; as long as there is a matching line number, add it to the %matches variable
    var %matches = %matches $readn

    ; and start the 'next' reading of the loop at the following line
    var %nr = $calc($readn +1)

    ; the maximum length of a variable (it's name + it's data) is 942 chars - 
    ; this line escapes a breaking of the script if there were too many matches
    if ($len(%matches) > 920) { .msg $chan Too many matches for $qt($2-) | return }
  }
  ; (end of loop) 

  ; if more than one match was found:
  if ($numtok(%matches,32) > 1) {
    .msg $chan Found $v1 quotes matching $qt($2-) at the following lines: %matches
  }

  ; if only one match was found:
  elseif ($v1 == 1) {
    tokenize 92 $read(quotes.txt,%matches)
    .msg $chan 04 $+ $chr(91) Quote $1 $chr(93) $+  $2
    .msg $chan 4Submitted by12: $3 4Rated12: $4
  }  

  ; if no match was found:
  else {
    .notice $nick $qt($2-) was not found in the quote database.
  }
}


note: untested smile
EDIT: fixed a minor error

Joined: Dec 2007
Posts: 24
T
Tzar469 Offline OP
Ameglian cow
OP Offline
Ameglian cow
T
Joined: Dec 2007
Posts: 24
That's great! I have one problem, though, is that I have more than just the quote on one line in quotes.txt. An example of a line is:

54\<Nick> Insert funny quote here\Nick2 on Wed Nov 14 18:26:07 2007.\1
(Line #\Quote\Added by and time\Rating)

In this case, if someone uses !qfind 54, it will return this line but "54" is not in the quote.Is there a way to only search what's in the actual quote?

Horstl, I thank you for commenting your code; it helps me understand how it works smile

Joined: Feb 2006
Posts: 546
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
you could search for $+(*\*,$2-,*\*\*)


"The only excuse for making a useless script is that one admires it intensely" - Oscar Wilde
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
This could be attained by rewriting the script using the /filter command, and this would be a *bit* faster. But in this case, I'd prefer changing only the read command line: to a regex search.

Change this line:
while ($read(quotes.txt,nw,* $+ $2- $+ *,%nr)) {
to:
while ($read(quotes.txt,ntr,$+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i),%nr)) {

Trying to explain the regular expression part $+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i)
(I'm not that good with regex, hope it works at all smile )
$+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i) -> sticking the other parts together with the provided search term "$2-"
$+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i) -> marking the beginn and end of the regular expression, the flag "i" makes the whole regular expression in-between the two // match case-insensitive
$+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i) -> one or more digits (the "line #" part)
$+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i) -> the backslash to separate the parts: line # - quote - added by and date - rating (the \ char is a char that had to be "escaped" inside regular expressions, else it would have another meaning)
$+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i) -> zero or more occurances of some char (this works like the * in ordinary wilcard comparisons)
$+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i) -> start and end of a "literal" part (that is: the text in between is matched as plain text (else a dot would not mean a literal dot etc... like the backslash thingie above)
$+(/\d+\\.*\Q,$2-,\E.*\\.+\\/i) -> one or more occurances of some char (this is the part "added by and time")

Note: You cannot use wildcards inside the matchword part any longer, as the asterisk char is now treated as 'plain text'.
That is: if someone types "!qfind test", the script will check the quotes part of your text file for wildcard matches of *test* - as it did before. But "!qfind *test*" would now mean a search for **test** (blue ones being literal asterisks, red ones being the 'wildcard search')


Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
Arf, I tend to make things more complex than they are, your suggestion would suffice.. whistle

Joined: Dec 2007
Posts: 24
T
Tzar469 Offline OP
Ameglian cow
OP Offline
Ameglian cow
T
Joined: Dec 2007
Posts: 24
Thank you!


Link Copied to Clipboard