[[project @ 2002-08-06 20:48:44 by unknown_lamer] unknown_lamer**20020806204844 DCC Chat now "works." It doesn't do anything useful, but you can /dcc chat the bot and talk at it. I will add hooks for DCC messages later. Probably some other bug fixes and stuff I forgot about, see the ChangeLog. ] { hunk ./ChangeLog 1 +2002-08-05 Clinton Ebadi + + * source/Parser.C (parseCTCP): Removed call to htonl and fixed + DCC! Ack, sockets take their arguments in network byte order so + there is no need to convert to host...now DCC _sort of_ works. + +2002-08-04 Clinton Ebadi + + * source/UserList.C (save): Increment iterator twice to get around + bug (see BUGS #2) + + * source/ServerQueue.C: Now sends SEND_* hooks instead of + triggered general hooks. + + * source/Interp.C (Startup): New scheme side defines: hooks/send/* + (* = the new SEND_ hooks, but lowercase). + + * source/BotInterp.H: New hook types (SEND_..., ... = ACTION, + CTCP, PUBLIC, MESSAGE). These are triggered on send messages. + hunk ./NEWS 14 -- Hooks are now executed when the bot sends a privmsg. This now makes - log scripts able to log what the bot said. This probably has other - uses too and shouldn't have any real impact on performance (since it - has to execute hooks on all incoming messages anyway, and there are - probably a lot more incoming than outgoing). hunk ./NEWS 18 -- There is a new macro for scripts--"not-from-me". This allows you to - protect your hooks from calling themselves because they trigger - themselves. See the manual for more about what it does - (Scripting->Misc Scripting Stuff). hunk ./NEWS 20 +- DCC CHAT now "works." You can connect to the bot and talk to to it, + but it doesn't do anything useful. +- New hooks: hooks/send/... where ... is one of action, ctcp, public, + or message. These are triggered when the bot does an + ACTION, sends a CTCP (_not_ a ctcp-reply), sends a PRIVMSG to a + channel, or sends a PRIVMSG to another user, respectively. There + will be more send hooks added later. hunk ./TODO 23 +* Make it possible to use Scheme functions in the Parser itself hunk ./TODO 26 +* Add hooks for DCC CHAT? hunk ./TODO 29 - - SSH? Telnet? DCC-Chat? - - Access to repl will require user to authenticate - - Allow server to be disabled at run because of security... -* Fix DCC support - - Note that Socket will have a buffer overflow problem with DCC - because it uses a buffer of 512 characters, and a DCC line is not - limited to 512 chars like an IRC line is. The question is: should - I rewrite readLine to be more general (allocate buffer on the - fly) or rename readLine to ircReadLine and add a more general - readLine? I think I could use a static std::string and have it - grow as needed, with a default size of 512. -* Make connecting to irc.oftc.net work...I wonder if their ircd is b0rked + - Telnet + - Store authorized users and passwords in bot.telnet file + - Bot master can add new telnet users + - MUST HAVE PASSWORD +* Make connecting to irc.oftc.net work...I wonder if their ircd is + broken +* DCC FILE support hunk ./bobot++.info 162 -(define (hello channel name) (if (string=? name "")}@* (bot:say -channel "Hello world!") (bot:say channel (string-append "Hello " -name "!"))) hunk ./bobot++.info 163 - (bot:addcommand "hello" hello #t 2 0) + (define (hello channel name) + (if (string=? name "") + (bot:say channel "Hello world!") + (bot:say channel (string-append "Hello " name "!"))) + + (bot:addcommand "hello" hello #t 2 0) hunk ./bobot++.info 170 - This will display ``Hello World!'' if called as !hello and ``Hello -World `USER''' if called as !hello USER. + This will display "Hello World!" if called as `!hello' and "Hello +World `USER'" if called as `!hello USER'. hunk ./bobot++.info 209 -the priority of the hook---higher priority hooks are executed first. +the priority of the hook--higher priority hooks are executed first. hunk ./bobot++.info 213 -optional name of the hook that defaults to ``DEFAULT''. If you set the +optional name of the hook that defaults to "DEFAULT". If you set the hunk ./bobot++.info 231 - - # of args - - `arg1': desc + - ARG1 ARG2 ... ARGN + - ARG1: desc hunk ./bobot++.info 234 - - `arg2': desc + - ARG2: desc hunk ./bobot++.info 238 - - `argN': desc + - ARGN: desc hunk ./bobot++.info 243 - - Description of the hook + - This hook is triggered when someone performs an action. hunk ./bobot++.info 245 - - # of args - - `arg1': desc + - FROM, TO, ACTION + - FROM: this is the address of the person that performed + the action in the form `USER ! NICK @ HOST' (without the + spaces). + + - TO: This is the target of the action, which is either a + channel or the Bot's nick. + + - ACTION: This is the text of the action. E.g. if someone + did `* foobar does baz', then ACTION would be the string + `"does baz"'. hunk ./bobot++.info 410 -``High Level'' Message Functions --------------------------------- +"High Level" Message Functions +------------------------------ hunk ./bobot++.info 418 -``Low Level'' Message Functions -------------------------------- +"Low Level" Message Functions +----------------------------- hunk ./bobot++.info 421 - The ``Low Level'' messaging functions allow you to do things like -send CTCP messages. You probably want to read rfc 2812 and the CTCP spec + The "Low Level" messaging functions allow you to do things like send +CTCP messages. You probably want to read rfc 2812 and the CTCP spec hunk ./bobot++.info 446 - Since a bot calls hooks on things it says, you have to be careful -about hooks that output text that might match itself. E.g. if you have -a hook that matches `"foo"' and the hook displays `"foo to the -whatsit?"', then the hook will call itself over and over until the -stack overflows! To protect against this I wrote the macro -`not-from-me'. You call it like this: `(not-from-me from (stmts if not -from bot) (stmts if from bot))'. E.g. - - (bot:addhook hooks/public "foo" - (lambda (f t p) - (not-from-me f ((bot:say t "foo to the what!"))))) - - This say ``foo to the what!'' to the channel that ``foo'' was said in -and do nothing otherwise. You can optionally specify an action to be -executed if the message is from the bot: - - (bot:addhook hooks/public "foo" - (lambda (f t p) - (not-from-me f ((bot:say t "foo to the what!")) - ((bot:say t "moof"))))) - - That will do the same thing as the first example, but the bot will -say ``moof'' if it said ``foo'' before. That probably isn't a very nice -thing to do, but it works as an example. You can have as many staments -as you want in the clauses. - hunk ./bobot++.info 475 +* exit-hook: Misc Scripting Stuff. hunk ./bobot++.info 513 -Node: Hooks5828 -Node: Creating a Hook6766 -Node: Hook Types7908 -Node: Scheme User Levels10381 -Node: Sending Messages11510 -Node: High Level Message Functions12107 -Node: Low Level Message Functions12325 -Node: Misc Scripting Stuff13084 -Node: Concept Index14710 -Node: Function Index14892 -Node: Variable Index15153 +Node: Hooks5852 +Node: Creating a Hook6790 +Node: Hook Types7929 +Node: Scheme User Levels10869 +Node: Sending Messages11998 +Node: High Level Message Functions12595 +Node: Low Level Message Functions12809 +Node: Misc Scripting Stuff13562 +Node: Concept Index13981 +Node: Function Index14163 +Node: Variable Index14424 hunk ./bobot++.texinfo 170 -@verb{| + +@example hunk ./bobot++.texinfo 173 - (if (string=? name "")}@* + (if (string=? name "") hunk ./bobot++.texinfo 178 -|} +@end example + hunk ./bobot++.texinfo 188 -hooks and tiny fugue (a MUD bot) hooks. The basic idea of a hook if -that you match a text against regular expression and call a function -if text in a message matches that regex. The different types of hooks -provided by Bobot++ correspond to the different classes of messages -that Bobot++ can recieve. A Hook also has several properties, -including its priority and whether or not it is a fallthrough -hook. Higher priority hooks are executed before lower priority hooks -and fallthrough hooks are executed before non-fallthrough hooks of the -same priority. A fallthrough hook can match and processing of hooks -will continue; as soon as the first non-fallthrough hooks matches -processing of hooks stops. +and tiny fugue (a MUD bot) hooks with a little bit of extra stuff +added in. The basic idea of a hook if that you match a text against +regular expression and call a function if text in a message matches +that regex. The different types of hooks provided by Bobot++ +correspond to the different classes of messages that Bobot++ can +recieve. A Hook also has several properties, including its priority +and whether or not it is a fallthrough hook. Higher priority hooks are +executed before lower priority hooks and fallthrough hooks are +executed before non-fallthrough hooks of the same priority. A +fallthrough hook can match and processing of hooks will continue; as +soon as the first non-fallthrough hooks matches processing of hooks +stops. hunk ./bobot++.texinfo 242 -# of args +@var{arg1} @var{arg2} ... @var{argn} hunk ./bobot++.texinfo 245 -@code{arg1}: desc +@var{arg1}: desc hunk ./bobot++.texinfo 247 -@code{arg2}: desc +@var{arg2}: desc hunk ./bobot++.texinfo 251 -@code{argN}: desc +@var{argN}: desc hunk ./bobot++.texinfo 266 -Description of the hook +This hook is triggered when someone performs an action. hunk ./bobot++.texinfo 268 -# of args +@var{from}, @var{to}, @var{action} hunk ./bobot++.texinfo 271 -@code{arg1}: desc +@var{from}: this is the address of the person that performed the +action in the form @samp{@var{user} ! @var{nick} @@ @var{host}} +(without the spaces). +@item +@var{to}: This is the target of the action, which is either a channel +or the Bot's nick. +@item +@var{action}: This is the text of the action. E.g. if someone did +@samp{* foobar does baz}, then @var{action} would be the string +@code{"does baz"}. hunk ./bobot++.texinfo 610 +@vindex exit-hook hunk ./bobot++.texinfo 616 -Since a bot calls hooks on things it says, you have to be careful -about hooks that output text that might match itself. E.g. if you have -a hook that matches @code{"foo"} and the hook displays @code{"foo to -the whatsit?"}, then the hook will call itself over and over until the -stack overflows! To protect against this I wrote the macro -@code{not-from-me}. You call it like this: @code{(not-from-me from -(stmts if not from bot) (stmts if from bot))}. E.g. +@c Since a bot calls hooks on things it says, you have to be careful +@c about hooks that output text that might match itself. E.g. if you have +@c a hook that matches @code{"foo"} and the hook displays @code{"foo to +@c the whatsit?"}, then the hook will call itself over and over until the +@c stack overflows! To protect against this I wrote the macro +@c @code{not-from-me}. You call it like this: @code{(not-from-me from +@c (stmts if not from bot) (stmts if from bot))}. E.g. hunk ./bobot++.texinfo 624 -@example -(bot:addhook hooks/public "foo" - (lambda (f t p) - (not-from-me f ((bot:say t "foo to the what!"))))) -@end example +@c @example +@c (bot:addhook hooks/public "foo" +@c (lambda (f t p) +@c (not-from-me f ((bot:say t "foo to the what!"))))) +@c @end example hunk ./bobot++.texinfo 630 -This say ``foo to the what!'' to the channel that ``foo'' was said in -and do nothing otherwise. You can optionally specify an action to be -executed if the message is from the bot: +@c This say ``foo to the what!'' to the channel that ``foo'' was said in +@c and do nothing otherwise. You can optionally specify an action to be +@c executed if the message is from the bot: hunk ./bobot++.texinfo 634 -@example -(bot:addhook hooks/public "foo" - (lambda (f t p) - (not-from-me f ((bot:say t "foo to the what!")) - ((bot:say t "moof"))))) -@end example +@c @example +@c (bot:addhook hooks/public "foo" +@c (lambda (f t p) +@c (not-from-me f ((bot:say t "foo to the what!")) +@c ((bot:say t "moof"))))) +@c @end example hunk ./bobot++.texinfo 641 -That will do the same thing as the first example, but the bot will -say ``moof'' if it said ``foo'' before. That probably isn't a very -nice thing to do, but it works as an example. You can have as many -staments as you want in the clauses. +@c That will do the same thing as the first example, but the bot will +@c say ``moof'' if it said ``foo'' before. That probably isn't a very +@c nice thing to do, but it works as an example. You can have as many +@c staments as you want in the clauses. hunk ./source/Bot.C 139 - // TODO: is it ok to delete iterators!?! - hunk ./source/Bot.C 525 - DCCConnection * d = new DCCConnection(this, from->getAddress(), + DCCConnection * d = new DCCConnection(this, from->getAddress (), hunk ./source/Bot.C 533 - logLine ("DCC Connection worked!"); + logLine ("DCC CHAT accepted from" + from->getAddress ()); hunk ./source/Bot.C 540 - for (std::map >::iterator it = channelList->begin(); + for (std::map >::iterator it = + channelList->begin(); hunk ./source/BotInterp.H 66 - PUBLIC_NOTICE, RAW, TIMER, TOPIC + PUBLIC_NOTICE, RAW, TIMER, TOPIC, + // send hooks + SEND_ACTION, SEND_CTCP, SEND_PUBLIC, SEND_MESSAGE hunk ./source/DCCConnection.C 25 -DCCConnection::DCCConnection(Bot *b, String n, unsigned long address, int port) +DCCConnection::DCCConnection(Bot *b, String n, unsigned long address, + int port) hunk ./source/DCCConnection.C 36 - hunk ./source/DCCConnection.H 26 +#include "DCCPerson.H" hunk ./source/DCCParser.C 3 +// Copyright (C) 2002 Clinton Ebadi hunk ./source/DCCPerson.C 3 +// Copyright (C) 2002 Clinton Ebadi hunk ./source/Interp.C 88 + scm_c_define ("hooks/send/public", scm_long2num (Hook::SEND_PUBLIC)); + scm_c_define ("hooks/send/message", scm_long2num (Hook::SEND_MESSAGE)); + scm_c_define ("hooks/send/action", scm_long2num (Hook::SEND_ACTION)); + scm_c_define ("hooks/send/ctcp", scm_long2num (Hook::SEND_CTCP)); hunk ./source/Main.C 74 - std::cerr << "Usage: " << name << " [--help] [--version] [--no-background]\n\t" + std::cerr << "Usage: " + << name + << " [--help] [--version] [--no-background]\n\t" hunk ./source/Main.C 82 - /* " -b Do not run in background.\n" - " -f file Use file as config file.\n" - " -d dir Use dir as current dir.\n" - " -c config Use config as config\n" - " -s config Use config as config (only search sysdir)\n" - " -u config Use config as config (only search userdir)\n" - " -D Debug mode (input/output printing and no background mode.\n"; - */ hunk ./source/Parser.C 94 - /* for (int i = 0; functions[i].name != 0; i++) - if (command == functions[i].name) { - functions[i].function(cnx, from, rest); - break; - } - */ + hunk ./source/Parser.C 853 - ntohl (strtoul ((const char *) st2.nextToken (), 0, 0)); + strtoul ((const char *) st2.nextToken (), 0, 0); hunk ./source/Parser.H 38 -// struct userFunctionsStruct { -// // String name; -// void (*function)(ServerConnection *, Person *, String, String); -// int minLevel; -// bool needsChannelName; +typedef void (*fptr)(ServerConnection *, Person *, String); + +// fptr is a parser function which may either be Scheme or C. fptr +// used to be what funptr is now, but I decided to make the bot even +// more extensible and it is now a function-like object that can be +// used just like it was a function pointer. + +// This will take a lot of work to make it actually work...lots of +// SMOBs have to be written :( + +// class fptr +// { +// private: +// typedef void (*funptr)(ServerConnection *, Person *, String); +// union +// { +// funptr Cfunc; +// #ifdef USESCRIPTS +// SCM Sfunc; +// #endif +// }; +// bool C; + +// public: +// ftpr () { Cfunc = 0; Sfunc = 0; C = true; }; +// operator= (funptr f) { Cfunc = f; C = true; }; +// operator= (SCM f) { Sfunc = f; C = false; }; + +// operator ()(ServerConnection * s, Person * p, String str) +// { +// if (C) +// Cfunc (s, p, str); +// else {} +// // ... SCM not supported for now +// } hunk ./source/Parser.H 156 - typedef void (*fptr)(ServerConnection *, Person *, String); hunk ./source/ServerQueue.C 94 - // hook stuff (only get action for now) hunk ./source/ServerQueue.C 95 - // I don't think it is useful to generate messages for other types - // of CTCP stuff. - puts (command); hunk ./source/ServerQueue.C 98 - Interp::bot->botInterp->RunHooks (Hook::ACTION, - MNICK+ " " + to + + Interp::bot->botInterp->RunHooks (Hook::SEND_ACTION, + MNICK + " " + to + hunk ./source/ServerQueue.C 109 + else + Interp::bot->botInterp->RunHooks (Hook::SEND_CTCP, + MNICK + " " + to + " " + + command + " " + message, + scm_listify (Utils:: + string2SCM (MNICK), + Utils:: + string2SCM (to), + Utils:: + string2SCM + (command), + Utils:: + string2SCM (message), + SCM_UNDEFINED)); hunk ./source/ServerQueue.C 225 - Interp::bot->botInterp->RunHooks (Hook::PUBLIC, + Interp::bot->botInterp->RunHooks (Hook::SEND_PUBLIC, hunk ./source/ServerQueue.C 236 - Interp::bot->botInterp->RunHooks (Hook::MESSAGE, + Interp::bot->botInterp->RunHooks (Hook::SEND_MESSAGE, hunk ./source/UserList.C 83 - ++it; // We skip the bot's entry + // FIXME: fix bug (see BUGS) and inc once + ++it; ++it; // We skip the bot's entry }