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.

hooking multiple commands to the same function - possible?

Discussion of Eggdrop's code and module programming in C.
M
MistaGee
Voice
Posts: 7
Joined: Tue Dec 06, 2005 8:19 am

hooking multiple commands to the same function - possible?

Post by MistaGee »

hi guys,

I'm intending to write a module for which I need to hook multiple commands to the same function but still keep the possibility to figure out which command was called later on. The issue is that I'm totally new to eggdrop module programming, so I don't know if I can do that.
I've checked the TCL writing already and found that it seems to not be possible, is it possible when writing a module?

My main problem is that I cannot simply write a single function for a single trigger since I'm trying to write a li'l interpreter and don't know which triggers I will use in my scripts later on...

3d1t: Is it possible to just catch all the stuff ppl say in the channel? If it is, I can use that and "search" for the triggers myself...

Thx & Greetz MGee
User avatar
De Kus
Revered One
Posts: 1361
Joined: Sun Dec 15, 2002 11:41 am
Location: Germany

Post by De Kus »

just make a function to call the other functions...
De Kus
StarZ|De_Kus, De_Kus or DeKus on IRC
Copyright © 2005-2009 by De Kus - published under The MIT License
Love hurts, love strengthens...
M
MistaGee
Voice
Posts: 7
Joined: Tue Dec 06, 2005 8:19 am

Post by MistaGee »

wow, I didn't ask for that great a detail, but thx anyway, that didn't help anything :twisted: :P

what do you mean, call the other functions? what functions? sry, but I just don't get what you mean... :?

I've made three functions already, one watching the channel, one waiting for /msgs and one keeping an eye at DCC which all cal the same interpreter function, but I don't want them to wait for a specific command or something. They're only supposed to call the interpreter on everything said, it will then determine what to do itself.

Greetz MGee
User avatar
De Kus
Revered One
Posts: 1361
Joined: Sun Dec 15, 2002 11:41 am
Location: Germany

Post by De Kus »

Ah sorry, after reading it a third time I figured what you are talking. Well my general idea is still the one you are looking for. Just add an addional argument to your orignal function. Then create a new function with the orignal arguments for each command. Now call your original function with the arguments and the addional argument which contains an identifier for where it was called from. I would advice an int value presented by a DEFINE string for better readability of the source :).

btw. if you are going to hook them via the tcl command "bind" you can skip the thing with the new function (but still create a new argument, it must be inserted at the first place) and just use something like: bind dcc o command {function arg1}
De Kus
StarZ|De_Kus, De_Kus or DeKus on IRC
Copyright © 2005-2009 by De Kus - published under The MIT License
Love hurts, love strengthens...
M
MistaGee
Voice
Posts: 7
Joined: Tue Dec 06, 2005 8:19 am

Post by MistaGee »

well, this is how far I have come yet:
http://mistagee.selfip.net:8080/mistagee/phparse.c

I'm trying to teach my eggdrop how2 use php since I _hate_ :evil: TCL, and I just don't know how to make the module react to the triggers ppl use in IRC. the rest should (!) work, I didn't yet have the chance to test it. (how come..? :P ) But for now, I only need help talking to my eggdrop.

This enourmous parser is used to allow the php script0rz to make the bot say something in IRC via printing the text in a specific syntax to stdout, which is then read by the eggdrop. In fact, this is the only function I'm pretty sure it'll work.

After having a look at it, you'll have better chances to give me a real clue ;p

Greetz MGee
User avatar
demond
Revered One
Posts: 3073
Joined: Sat Jun 12, 2004 9:58 am
Location: San Francisco, CA
Contact:

Post by demond »

check eggdrop source, see how Tcl binds work (in your case, [bind pub])
connection, sharing, dcc problems? click <here>
before asking for scripting help, read <this>
use

Code: Select all

 tag when posting logs, code
t
turbo0O
Voice
Posts: 4
Joined: Sat Dec 31, 2005 3:19 am

progress?

Post by turbo0O »

Have you made any further progress with your eggdrop PHP parser? I've been thinking about doing something like this for awhile now.
M
MistaGee
Voice
Posts: 7
Joined: Tue Dec 06, 2005 8:19 am

Post by MistaGee »

well I haven't come too far, been busy with other stuff.... we could write the plugin together though, I thought of checking how apache accesses PHP and just do the same with eggdrop...
I need to read and understand the apache and eggdrop source now and learn how2 write eggdrop modules... quite a pile of work to do ;)

It's just that atm I don't have too much time left to do that...

Greetz MGee
K
Kappa007
Voice
Posts: 38
Joined: Tue Jul 26, 2005 9:53 pm

Post by Kappa007 »

Hmmm...your problem sounds like the same thing I tried to do.

But lets see...my problem was:

I wanted to have it that way:

Code: Select all

!token1 cmd1 --> myfunc()
!token1 cmd2 --> myfunc()
!token1 cmd3 --> myfunc()
!token2 cmd1 --> myfunc()
!token2 cmd2 --> myfunc()
Unfortunatly you cannot bind function names with spaces.
Also I wanted to have a single input function for all commands regged by my module.
The problem that showed up was that eggdrop calls the bound function without the actual command token which triggered the event.


The solution I now use is rather tricky and was quite time consuming.
It also requires modifying the eggdrop sources:
  • When using add_builtins() with the cmd_t structure I use "cmd_t.funcname" to kinda tag my function
  • In check_tcl_bind() [tclhash.c] that tag appears in tcl_cmd_t.func_name.
    That value can be used to check for functions bound by your module
  • check_tcl_dcc() binds the command arguments, nick etc. to the Tcl variables ("_dcc1" etc).
    There I bind the command token to my own variable using Tcl_SetVar.
  • In check_tcl_bind() I extract that variable from Tcl (Tcl_GetVar)and modify the command arguments to contain the command token before executing the trigger.
There might also be another possibility to achieve the same goal:
Bind the commands to MSGM, PUBM and FILT instead of MSG, PUB and DCC.
Those pass the whole text including the command token.
However they are matched against the whole line and not just via the start of the line and thus might trigger your binds too often.

MSGM (stackable)

bind msgm <flags> <mask> <proc>
procname <nick> <user@host> <handle> <text>

Description: matches the entire line of text from a /msg with the mask. This is useful for binding Tcl procs to words or phrases spoken anywhere within a line of text.
---------
PUBM (stackable)

bind pubm <flags> <mask> <proc>
procname <nick> <user@host> <handle> <channel> <text>

Description: just like MSGM, except it's triggered by things said on a channel instead of things /msg'd to the bot. The mask is matched against the channel name followed by the text and can contain wildcards. Also, if a line triggers a PUB bind, it will not trigger a PUBM bind.
---------
FILT (stackable)

bind filt <flags> <mask> <proc>
procname <idx> <text>

Description: party line and file system users have their text sent through filt before being processed. If the proc returns a blank string, the text is considered parsed. Otherwise, the bot will use the text returned from the proc and continue parsing that.

Unfortunatly I found out about that just today after putting in the solution mentioned first :D
If you need any more hints post below...

Regards,
Kappa
M
MistaGee
Voice
Posts: 7
Joined: Tue Dec 06, 2005 8:19 am

Post by MistaGee »

thanxXx a great lot!

Unfortunately I don't have too much time for this, so I had to delay the project, but soon I'll have two months of holidays and I guess I'ma continue my project then and see how far I can get.

Greetz MGee
O
OpEn_FiRe
Voice
Posts: 2
Joined: Sun Jan 29, 2006 10:10 am

Post by OpEn_FiRe »

If i understood this right it wouldnt be necessary to modify the eggdrop code just to find out wich bind called that proc...
when a bind is triggered it saves the match used in a variable called lastbind.
So all you need to do is add the lastbind to the global part of your proc and u will have wich bind started that proc... Very simple when u read the documentation that comes with eggdrop actually
K
Kappa007
Voice
Posts: 38
Joined: Tue Jul 26, 2005 9:53 pm

Post by Kappa007 »

OpEn_FiRe wrote:If i understood this right it wouldnt be necessary to modify the eggdrop code just to find out wich bind called that proc...
when a bind is triggered it saves the match used in a variable called lastbind.
So all you need to do is add the lastbind to the global part of your proc and u will have wich bind started that proc... Very simple when u read the documentation that comes with eggdrop actually
Indeed!
Tcl_SetVar(interp, "lastbind", (char *) fullmatch, TCL_GLOBAL_ONLY);
Just one line above the changes I applied *doh*
Guess I should have read the docs 8)
M
MistaGee
Voice
Posts: 7
Joined: Tue Dec 06, 2005 8:19 am

Post by MistaGee »

I'm reading the eggdrop source code right now in order to find out how the TCL module makes eggdrop call the function that checks the binds whenever needed, but I can't figure out how this is actually done since the author chose to not add any helpful comments at all.

I'm not intending to implement this /msg and DCC stuff right now, so lezz just pretend it wouldn't exist until the "normal" chat binds work :)

Can I actually register my chat binds with eggdrop, so that eggdrop calls a function in my module everytime a chatter uses the bind? Then I'd just have to check which bind it was, and make PHP execute the according script.

If not:
Can I tell Eggdrop to call a function everytime any chatter says something and then check for a bind myself?

Both ways, I will need eggdrop to tell my function what the user actually said, and I'll need some way to figure out which bind was actually used.

Finding out which chat bind belongs to which file won't be too hard, I'll just implement that with a register_bind() function or something in the php scripts, but I need a command to add into eggdrop.conf which tells my module to use a specific php script.
How do I introduce a command to eggdrop which is intended to be used in the config? Can I actually use every command in there or do I have to do something special?

Greetz MGee
K
Kappa007
Voice
Posts: 38
Joined: Tue Jul 26, 2005 9:53 pm

Post by Kappa007 »

Not quite sure what you mean but as OpEn_FiRe pointed out, if you bind
!cmd1 -> myfunc()
!cmd2 -> myfunc()
!cmd3 -> myfunc()

Just call Tcl_GetVar(...,"lastbind") in myfunc() to find out what command (!cmd1, !cmd2, !cmd3) triggered it.
M
MistaGee
Voice
Posts: 7
Joined: Tue Dec 06, 2005 8:19 am

Post by MistaGee »

I think I understood Eggdrop module coding by now and I know a little bit what I'm doing... How do I have to use this Tcl_GetVar function? Atm I'm doing it like this:

Code: Select all

	char* used_bind;
	used_bind = Tcl_GetVar(interp, "lastbind", 0);
is that correct? (It actually does compile...)

Still I need an idea how to establish the communication to the PHP part of the module, and until I found out how to do that, I won't be able to develop the eggdrop part further...

Greetz MGee
Post Reply