From 1e49969a03854f898dac9f8c1e0b0970b3b363a5 Mon Sep 17 00:00:00 2001 From: Geo Date: Thu, 2 Nov 2023 23:03:40 -0400 Subject: [PATCH] Add got-chanlist event bind type --- doc/sphinx_source/using/tcl-commands.rst | 1 + src/mod/irc.mod/chan.c | 1 + src/mod/module.h | 3 +++ src/modules.c | 4 +++- src/tclhash.c | 26 +++++++++++++++++++++++- src/tclhash.h | 1 + src/tclmisc.c | 8 ++++++-- 7 files changed, 40 insertions(+), 4 deletions(-) diff --git a/doc/sphinx_source/using/tcl-commands.rst b/doc/sphinx_source/using/tcl-commands.rst index 34399b0e9..2f3ebafa3 100644 --- a/doc/sphinx_source/using/tcl-commands.rst +++ b/doc/sphinx_source/using/tcl-commands.rst @@ -3445,6 +3445,7 @@ The following is a list of bind types and how they work. Below each bind type is disconnect-server - called when we disconnect from our IRC server fail-server - called when an IRC server fails to respond hidden-host - called after the bot's host is hidden by the server + got-chanlist - called after Eggdrop receives the channel userlist from the server Note that Tcl scripts can trigger arbitrary events, including ones that are not pre-defined or used by Eggdrop. diff --git a/src/mod/irc.mod/chan.c b/src/mod/irc.mod/chan.c index 036eb06e6..94807f6e8 100644 --- a/src/mod/irc.mod/chan.c +++ b/src/mod/irc.mod/chan.c @@ -1289,6 +1289,7 @@ static int got315(char *from, char *msg) sync_members(chan); chan->status |= CHAN_ACTIVE; chan->status &= ~CHAN_PEND; + check_tcl_event_arg("got-chanlist", chname); if (!ismember(chan, botname)) { /* Am I on the channel now? */ putlog(LOG_MISC | LOG_JOIN, chan->dname, "Oops, I'm not really on %s.", chan->dname); diff --git a/src/mod/module.h b/src/mod/module.h index 1fd109b5c..f39b86c8c 100644 --- a/src/mod/module.h +++ b/src/mod/module.h @@ -527,6 +527,9 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr #define USERENTRY_ACCOUNT (*(struct user_entry_type *)(global[316])) #define get_user_by_account ((struct userrec * (*)(char *))global[317]) #define delaccount_by_handle ((int(*)(char *,char *))global[318]) +#define check_tcl_event_arg ((void (*) (const char *,const char *))global[319]) +/*320 - 323 */ + diff --git a/src/modules.c b/src/modules.c index e1712489b..29045cd1c 100644 --- a/src/modules.c +++ b/src/modules.c @@ -625,7 +625,9 @@ Function global_table[] = { /* 316 - 319 */ (Function) & USERENTRY_ACCOUNT, /* struct user_entry_type * */ (Function) get_user_by_account, - (Function) delhost_by_handle + (Function) delhost_by_handle, + (Function) check_tcl_event_arg +/* 320 - 323 */ }; void init_modules(void) diff --git a/src/tclhash.c b/src/tclhash.c index 5c9b02862..4b7160383 100644 --- a/src/tclhash.c +++ b/src/tclhash.c @@ -51,6 +51,7 @@ static int builtin_cron STDVAR; static int builtin_char STDVAR; static int builtin_chpt STDVAR; static int builtin_chjn STDVAR; +static int builtin_evnt STDVAR; static int builtin_idxchar STDVAR; static int builtin_charidx STDVAR; static int builtin_chat STDVAR; @@ -235,7 +236,7 @@ void init_bind(void) H_bcst = add_bind_table("bcst", HT_STACKABLE, builtin_chat); H_away = add_bind_table("away", HT_STACKABLE, builtin_chat); H_act = add_bind_table("act", HT_STACKABLE, builtin_chat); - H_event = add_bind_table("evnt", HT_STACKABLE, builtin_char); + H_event = add_bind_table("evnt", HT_STACKABLE, builtin_evnt); H_die = add_bind_table("die", HT_STACKABLE, builtin_char); H_log = add_bind_table("log", HT_STACKABLE, builtin_log); #ifdef TLS @@ -593,6 +594,21 @@ static int builtin_chjn STDVAR return TCL_OK; } +static int builtin_evnt STDVAR +{ + Function F = (Function) cd; + + BADARGS(2, 3, " event ?arg?"); + + CHECKVALIDITY(builtin_evnt); + if (argc==2) { + F(argv[1]); + } else { + F(argv[1], argv[2]); + } + return TCL_OK; +} + static int builtin_idxchar STDVAR { Function F = (Function) cd; @@ -1212,6 +1228,14 @@ void check_tcl_event(const char *event) MATCH_EXACT | BIND_STACKABLE); } +void check_tcl_event_arg(const char *event, const char *arg) +{ + Tcl_SetVar(interp, "_event1", (char *) event, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "_event2", (char *) arg, TCL_GLOBAL_ONLY); + check_tcl_bind(H_event, event, 0, " $::_event1 $::_event2", + MATCH_EXACT | BIND_STACKABLE); +} + int check_tcl_signal(const char *event) { int x; diff --git a/src/tclhash.h b/src/tclhash.h index 8be6fed4d..669d3bd37 100644 --- a/src/tclhash.h +++ b/src/tclhash.h @@ -97,6 +97,7 @@ void check_tcl_nkch(const char *, const char *); void check_tcl_away(const char *, int, const char *); void check_tcl_chatactbcst(const char *, int, const char *, tcl_bind_list_t *); void check_tcl_event(const char *); +void check_tcl_event_arg(const char *, const char *); int check_tcl_signal(const char *); void check_tcl_die(char *); void check_tcl_log(int, char *, char *); diff --git a/src/tclmisc.c b/src/tclmisc.c index c6d15804c..cfa6d5420 100644 --- a/src/tclmisc.c +++ b/src/tclmisc.c @@ -646,9 +646,13 @@ static int tcl_reloadhelp STDVAR static int tcl_callevent STDVAR { - BADARGS(2, 2, " event"); + BADARGS(2, 3, " event ?arg?"); - check_tcl_event(argv[1]); + if (argc == 2) { + check_tcl_event(argv[1]); + } else { + check_tcl_event_arg(argv[1], argv[2]); + } return TCL_OK; }