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.

need to be able to retrigger binds

Old posts that have not been replied to for several years.
Locked
j
jamie3
Voice
Posts: 10
Joined: Tue Dec 23, 2003 8:25 am

need to be able to retrigger binds

Post by jamie3 »

hi, i have an eggdrop script that needs to decrypt incoming text, and then force the eggdrop to retrigger any appropriate binds on the now decrypted text.

is there any way to do this?
if not, any suggestions for an alternative way, such as interograting any registered binds programmatically and matching their conditions manually in a loop.

if its not possible in the current eggdrop code, any hints of where to go in the code to implement such a ManualApplyBinds function?
j
jamie3
Voice
Posts: 10
Joined: Tue Dec 23, 2003 8:25 am

Post by jamie3 »

assuming there is no way to tell eggdrop to process binds for an abitrary constructed string/nick/chan..

i did see that there is a command for interrogating the system for all registered binds:

http://tcl.powersource.cx/eggtclh09.php

binds ?type/mask?
Returns: a list of Tcl binds, each item in the list is a sublist of five elements: {<type> <flags> <name> <hits> <proc>}
Module: core

so i wonder what the possibility is of writing a function that is passed arguments for (type,flags,nick,text,host,etc...) and then searches through all registered binds (using list returned by binds command), and manully triggers the bound procedures..

seems like a lot of work but might work - the only thing im concerned about is that this 5-tuple entry returned by binds does not seem to hold all the relevant info for a bin.

any ideas?
User avatar
stdragon
Owner
Posts: 959
Joined: Sun Sep 23, 2001 8:00 pm
Contact:

Post by stdragon »

Yeah you could do that. The binds command will return all the binds and what they listen for. You probably want the "raw" table. So, when you decrypt your text, you can just execute the proper bind with the decrypted data. It will be hard if *all* the text is encrypted, because then you'd have to handle all of the raw binds. But if it's just privmsg's or something it should be pretty easy.

What information does the [binds] thing not give you?

{raw -|- 438 0 *raw:438}

This means, a raw bind, with no flags, listening for "438", with 0 triggers, calling the proc *raw:438

I think that's all you need.
j
jamie3
Voice
Posts: 10
Joined: Tue Dec 23, 2003 8:25 am

Post by jamie3 »

thx stdragon, maybe binds does hold all the info i need - i was worried that the mask in bind pubm might be missing, but maybe its returned in the 'command' slot of the tuple.

i'm a c++ programmer without much experience in tcl/eggdrop, so i'm just finding my way in the dark here.

i think with a combination of parsing binds and implementing functions that replace putserv,etc.. ill be able to write the remaining functions that i need, to encrypt and decrypt text on the fly for other installed scripts without modifying them.

this is for an open source encryption/decryption addon called mircryption (http://mircryption.sourceforge.net) if someone is willing to help with some of the coding - which i would welcome.

this is a newbie question but if i'm inside a procedure which was triggered by a bind call with the normal {nick host hand chan text}arguments, and i parse a tuple from the binds list and i get an entry for pubm, which has {pubm,flags, mask,hits,proc}, is there an easy way for me to compare if my current triggering meets the flags and mask for this bind?

is my question clear?
in other words, i have my own bind like this:
bind pub - "mcps" receiveencrypted

with the procedure
proc receivecrypted {nick host hand chan text} {

inside receiveencrypted i want to first decrypt the incoming text and then iterate through the other binds.
and let's say i find one like
{pubm m|m "specialchan !help" 0 dohelp}

so what i want to do is match the m|m against my current flags, match "specialchan !help" against my current channel and DECRYPTED text, and then invoke dohelp if they match.

question is, what's the easiest way to match the m|m against my current flags, match "specialchan !help" against my current channel and DECRYPTED text?
User avatar
stdragon
Owner
Posts: 959
Joined: Sun Sep 23, 2001 8:00 pm
Contact:

Post by stdragon »

Well here's something to get you started, I didn't test it (except bind_mask_to_regexp a little bit).

Code: Select all

proc bind_mask_to_regexp {mask} {
  regsub -all {\.|\(|\+|\^|\$|\\|\[|\|} $mask {\\&} mask
  regsub -all "\{" $mask {\\&} mask
  regsub -all {\*} $mask {.*} mask
  regsub -all {\?} $mask {.} mask
  regsub -all {%} $mask {[^\s]+} mask
  regsub -all {~} $mask {[\s]+} mask
  return "^$mask\$"
}

proc encrypted_pubm {nick uhost hand chan text} {
  set line [decrypt_somehow $text]
  foreach bind [binds pubm] {
    foreach {table flags mask hits callback} $bind {}
    if {![string equal "-|-" $mask] && ![matchattr $hand $flags $chan]} { continue }
    set mask [bind_mask_to_regexp $mask]
    if {![regexp -nocase -- $mask $line]} { continue }
    catch { eval $callback [list $nick $uhost $hand $chan $line] }
  }
  return 0
}
Something like that anyway. Let me know if you have questions.
User avatar
stdragon
Owner
Posts: 959
Joined: Sun Sep 23, 2001 8:00 pm
Contact:

Post by stdragon »

Oh ya, I guess it should be

regexp -nocase -- $mask "$chan $line"
j
jamie3
Voice
Posts: 10
Joined: Tue Dec 23, 2003 8:25 am

Post by jamie3 »

thank you so much stdragon - this is just what i needed - something to get me started. i will report my progress, and ask if i have more questions.
j
jamie3
Voice
Posts: 10
Joined: Tue Dec 23, 2003 8:25 am

Post by jamie3 »

Here's my version of the code with comments and debugging info, based on stdragon's code.

Seems to be working great - thank you so much stdragon you saved my sanity.

Note the stdrag_triggerbinds function is called with the decrypted version of $text, so this function below is basically a way to send the arguments comtype nick uhost hand chan text and have this function invoke all binds that would be triggered automtically if this command had been received normally.

It's currently set up only to work with pub,pubm,notc,topc,msg,msgm, but should be easy to modify for others. you pass the comtype argument to indicate what kind of bind you are looking to match. it tries to repsect stacking behavior (did i do it right?)

Any suggestions and bug fixes are welcome, i haven't tested all kinds of mask and flag combinations. Sorry that indenting is not showing here.

thanks again stdragon.


#######################################################
# STDRAGON FUNCTIONS - for iterating through binds to manually trigger them
# http://forum.egghelp.org/viewtopic.php?p=31744#31744

proc stdrag_triggerbinds {comtype nick uhost hand chan text} {
# this procedure iterates through all registered binds, and manually triggers those that match
# returns a count of the number of triggers executed

# debugging
putlog "DEBUG in triggerbinds: $comtype $nick $uhost $hand $chan $text"

# walk through all binds and look for matches
set triggercount 0
foreach bind [binds] {

# grab the the elements from current bind table entry
foreach {table flags mask hits callback} $bind {}

# debugging
putlog "DEBUG checking against: $table $flags $mask $hits $callback"

# dont retrigger ourselves!
if {$mask == "mcps" || $mask =="+OK"} { continue }

# debugging
putlog "DEBUG at stage 0"

# check if this is one of the kinds of binds we handle (ATTN: check case), if not continue to next entry
if {$table != "pub" && $table != "pubm" && $table != "msg" && $table != "notc" && $table != "topc"} { continue }

# debugging
putlog "DEBUG at stage 1"

# check if this is the kind of bind we want to match based on comtype; if they are equal its good
set commandmatch 0
if {$comtype == $table} { set commandmatch 1 }
if {$comtype == "pub" && $table == "pubm"} { set commandmatch 1 }
if {$comtype == "pubm" && $table == "pub"} { set commandmatch 1 }
if {$comtype == "msg" && $table == "msgm"} { set commandmatch 1 }
if {$comtype == "msgm" && $table == "msg"} { set commandmatch 1 }
# if its not compatible, continue to next table entry
if {$commandmatch == 0} { continue }

# debugging
putlog "DEBUG at stage 2"

# check the flags of the channel if it doesnt match, continue to next bind
if {![string equal "-|-" $flags] && ![matchattr $hand $flags $chan]} { continue }

# now convert the bind mask to a regexp in preparation for comparing it to text
set cmask [stdrag_bind_mask_to_regexp $mask]

# debugging
putlog "DEBUG at stage 3 with converted mask = $mask and converted mask = $cmask and text = $text"

# compare the mask against chan .+ text if its pubm, or again text otherwise
if {$table == "pubm"} {
if {![regexp -nocase -- $cmask "$chan $text"]} {
putlog "DEBUG cmask did not match '$chan $text'"
continue
}
} elseif {$table == "topc"} {
if {![regexp -nocase -- $cmask "$chan $text"]} {
continue
}
} elseif {![regexp -nocase -- $cmask $text]} {
continue
}

# debugging
putlog "DEBUG at stage 4"

# ok we got a matching bind we want to retrigger, so call it
catch { eval $callback [list $nick $uhost $hand $chan $text] }

# debugging
putlog "DEBUG at stage 5"

# increment triggercount
incr triggercount

# should we stop iterating (when we hit a pub or msg we stop, but pubm or mesgm, or notc we dont)
if {$table == "pub" || $table == "msg" } { break }
}
return $triggercount
}


proc stdrag_bind_mask_to_regexp {mask} {
# helper function to convert an eggdrop bind text mask into a regular expression pattern
regsub -all {\.|\(|\+|\^|\$|\\|\[|\|} $mask {\\&} mask
regsub -all "\{" $mask {\\&} mask
regsub -all {\*} $mask {.*} mask
regsub -all {\?} $mask {.} mask
regsub -all {%} $mask {[^\s]+} mask
regsub -all {~} $mask {[\s]+} mask
return "^$mask\$"
}
#######################################################
j
jamie3
Voice
Posts: 10
Joined: Tue Dec 23, 2003 8:25 am

Post by jamie3 »

ok, quite a few fixes and additions to the above code, but its working great - thanks for all the help here and also in #egghelp on efnet.

if anyone is curious about the final script, which reroutes input and output through decrypt/crypt procedures, you're welcome to borrow the code:

http://mircryption.sourceforge.net
http://mircryption.sourceforge.net/Extr ... sfuncs.tcl

thanks again stdragon for helping me exactly with the hardest part of the work that i had no idea how to do.
j
jamie3
Voice
Posts: 10
Joined: Tue Dec 23, 2003 8:25 am

Post by jamie3 »

one issue with reprocessing the binds manullay is that the list returned by the [binds] command is alphabetized.

i'm not sure what order eggdrop parses them in normally - but this could conceivably make the manual parsing of binds occur in a different order than normal bind triggers. im also not sure about the behavior in eggdrop when encountering multiple pub and pubm matches. documentation says a pub will block a matching pubm, but doesnt really talk about order.
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

In the source code of the bot, if the return code from the PUB bind trigger, say it was sucessful in triggering a bind, then no PUBM binds are called at all for that string of text.

In other words, you should trigger PUB binds first, if one matches, break out of the triggering loop (you can only call one single PUB bind, so this will speed your code up) and ignore the PUBM binds.

If it doesn't trigger a PUB bind (IE, the loop completes without a match), then you can look at the PUBM stuff.

As for the order in which binds are called, I havn't honestly looked. Have you tried creating some test code to test order?
j
jamie3
Voice
Posts: 10
Joined: Tue Dec 23, 2003 8:25 am

Post by jamie3 »

i've implemented the process of checking first for a pub and then only pubms if no pub matches.

the unresolved issue is that [binds] returns an alphabetized list and eggdrop *seems* to order newest binds ahead of older.
Locked