This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

problem

Old posts that have not been replied to for several years.
Locked
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

problem

Post by caesar »

Using this code:

Code: Select all

set badfile "badword.txt"

bind pubm - * pubm:badword

proc pubm:badword {nick uhost hand channel args } {
global badfile
if {![file exists $badfile]} {
putlog "Error: Le $badfile de dossier n'existent pas."
return }
set file [open "$badfile" r]
set line [gets $file]
while {![eof $file]} {
foreach word [split $args] { 
if {![string match "$word" [split $line]]} { continue } 
set found 1
break }
}
catch {close $file}
if {![info exists found]} { return 0 }
putlog "found"
}
my eggdrop dies. Where have I made a mistake? I know I've made one but I can find it.
Once the game is over, the king and the pawn go back in the same box.
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

First off, I sugesta programmers file editor is used. Your code allways seems so hard to read, with close braces placed pretty much where you want.

Second, you may find it handy to post the error message. This usualy tells you the error without too muhc issue.

Third, your use of $args.

Forth, you only ever call the "gets" command once. This is causing it to loop forever, as it checks the one line over and over, never reaching EOF.
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

First, I haven't understood what you ment to say.. second, I have fixed it a bit and looks like this:

Code: Select all

set badfile "badword.txt"

bind pubm - * pubm:badword

proc pubm:badword {nick uhost hand channel text} {
global badfile
if {![file exists $badfile]} {
putlog "Error: Le $badfile de dossier n'existent pas."
return }
foreach word [split $text] {
set file [open "$badfile" r]
while {![eof $file]} {
set line [gets $file]
if {![string match "$word" $line]} { continue }
putserv "PRIVMSG $channel :yes"
catch {close $fid}
return }
break }
putserv "PRIVMSG $channel :nope"
}
And what you wanted to tell me about the $args? But, now the problem is that he dosen't do the foreach thing corectly..
Once the game is over, the king and the pawn go back in the same box.
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

1: You code is very bunched up.

You do an IF, open a brace and then goto a new line. However, when you close the brace, you place it at the end of a line, rathet than a on a new one.

While this isn't wrong, and is perfectly valid, it makes for hard to read code.

2: Indenting.

Along with doing braces, you should indent your code. It makes for far simpler reading again. You can tell what code, bellongs in which brace.

If you start doing a mass of if, while, foreach and for loops, you can find you get lost on howmany braces you have open. Indenting from the off, will allow you too know how many braces need closing, and making for simple backtracking.

Your code (first post) can be represented as follows.

Code: Select all

set badfile "badword.txt" 

bind pubm - * pubm:badword 

proc pubm:badword {nick uhost hand channel args } { 
  global badfile 
  if {![file exists $badfile]} { 
    putlog "Error: Le $badfile de dossier n'existent pas." 
    return
  } 
  set file [open "$badfile" r] 
  set line [gets $file] 
  while {![eof $file]} { 
    foreach word [split $args] { 
      if {![string match "$word" [split $line]]} { continue } 
      set found 1 
      break
    } 
  } 
  catch {close $file} 
  if {![info exists found]} { return 0 } 
  putlog "found" 
}
See how you can tell where in the code you are. I do not state you have to take this approach, but it's far simpler to read.

Now back to the issues.

Scrap the code from the second post, it's more flawed than the first.

In the code above (in this post), you need to move the "gets" command. Unless it's in the loop, EOF will never be called.

What exactly are you trying to match in the foreach loop:
The whole line of IRC input?
Each word of IRC input?

If it's the whole line, then you don't even need the foreach loop, or $args.

It's it's each word, then you shouldn't be using $args (it is currently causing you to match against the whole line).

Otherwise, there isn't enything else wrong.
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

In 'badword.txt' are some words placed like this:

Code: Select all

first_word
second_word
.. etc.
and I've wanted it to do the foreach and compare all the words from the line said in channel with all the words in the file.

Oh, and also, tryed the code you have previously posted and same problem as my first code: freeze..
Once the game is over, the king and the pawn go back in the same box.
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

then do not use $args.

The foreach loop should be a matter of changing the variable name.
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

I've replaced 'args' with 'text' and same thing, no difference at all.
Once the game is over, the king and the pawn go back in the same box.
e
egghead
Master
Posts: 481
Joined: Mon Oct 29, 2001 8:00 pm
Contact:

Post by egghead »

nvm.
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

I have gone over and over the code, and it hit me on the, 1000 ish attempt.

Code: Select all

{![string match "$word" [split $line]]} 
Are you trying to do a direct match, or using wildcards?

If wildcards, this this is the right way to do it, however, you will need to remove the "split" command, and possibly use the -nocase option (otherwise the match can be missed with mixed case)

If a direct match, you may want to use the "string equal" command. Again, you will need to remove the "split" command, and possible use the -nocase option.,
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

I was looking for a direct match. I've removed all '[split]' and changed that line with 'if {![string equal "$word" $line]} { continue } ' and I still get the same result. It eats about 98% CPU and mem.. and freezes.
Once the game is over, the king and the pawn go back in the same box.
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

Then you still havn't moved the "gets" command to the correct place.
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Oh. Here is the code that seems to be working fine (no more freeze):

Code: Select all

set badfile "badword.txt" 

bind pubm - * pubm:badword 

proc pubm:badword {nick uhost hand channel text} { 
  global badfile 
  if {![file exists $badfile]} { 
    putlog "Error: Le $badfile de dossier n'existent pas." 
  return } 
  foreach word $text { 
    set file [open "$badfile" r] 
    while {![eof $file]} { 
      set line [gets $file] 
      if {![string equal "$word" $line]} { continue } 
      putserv "PRIVMSG $channel :yes" 
      catch {close $fid} 
    return } 
  break } 
  putserv "PRIVMSG $channel :nope" 
}
But now the problems is that he dosen't try to match all words typed in channel. The 'badword.txt' has in it 'foo' and when I type 'foo' I get an yes (as it's working), but when I try a something foo is not working, I get an nope. Also I've tryed with the string match and again same result: nope.
Once the game is over, the king and the pawn go back in the same box.
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

Listen, I tried, but I don't seem to get anywhere.

There was no need to move the "foreach" out of the while loop. It is slower when outside the while loop, as it has to open, close, open, close, open, close (one open and close per word in IRC), rather the open and close once.

Second, I noticed that you are not even closing the file. SO for each word, you open a file, but don't close it (only when the word matches).
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Problem fixed:

Code: Select all

set badfile "badword.txt" 

bind pubm - * pubm:badword 

proc pubm:badword {nick uhost hand channel args } {
global badfile 
if {![file exists $badfile]} { 
  putlog "Error: Le $badfile de dossier n'existent pas." 
  return 
} 
set file [open "$badfile" r] 
while {![eof $file]} { 
  set line [gets $file] 
  foreach word [split $args] { 
    if {![string equal "$word" $line]} { continue } 
    set found 1 
    break 
  } 
} 
catch {close $file} 
if {![info exists found]} { return 0 } 
putserv "PRIVMSG $channel :yes" 
}
Thank you. Now is working, a bit slow but is working.. :)
Once the game is over, the king and the pawn go back in the same box.
Locked