[project @ 2002-08-06 20:48:44 by unknown_lamer]
authorunknown_lamer <unknown>
Tue, 6 Aug 2002 20:48:44 +0000 (20:48 +0000)
committerunknown_lamer <unknown>
Tue, 6 Aug 2002 20:48:44 +0000 (20:48 +0000)
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.

17 files changed:
ChangeLog
NEWS
TODO
bobot++.info
bobot++.texinfo
source/Bot.C
source/BotInterp.H
source/DCCConnection.C
source/DCCConnection.H
source/DCCParser.C
source/DCCPerson.C
source/Interp.C
source/Main.C
source/Parser.C
source/Parser.H
source/ServerQueue.C
source/UserList.C

index cae48af..cbd5a0e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2002-08-05  Clinton Ebadi  <clinton@unknownlamer.org>
+
+       * 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  <clinton@unknownlamer.org>
+
+       * 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.
+
 2002-08-01  Clinton Ebadi  <clinton@unknownlamer.org>
 
        * source/Bot.C (set_log_file): Oops! Fixed logging. Now the bot
diff --git a/NEWS b/NEWS
index da04de1..dc46be3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,21 +11,19 @@ IMPORTANT NOTES:
 =====================================================================
 
 Version 2.1.1: foom
-- 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).
 - You can now "name" a hook using an extra arg to bot:addhook. This
   name can be used to have multiple hooks of the same type with the
   same regexp. The default name is "DEFAULT" so don't use that as the
   name for your hooks.
-- 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).
 - Logging now works again (oops, I didn't realize I broke it until I
   started to work on DCC).
+- 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.
 
 Version 2.1.0: Zug Zug
 - Hooks can now be fallthrough or non fallthrough. You can set a hooks
diff --git a/TODO b/TODO
index 8b374d7..9872758 100644 (file)
--- a/TODO
+++ b/TODO
@@ -20,22 +20,19 @@ Scripting:
 * Finish adding commands to Scheme for sending messages
    (e.g. bot:send-CTCP to send a CTCP message)
 * Add util functions for doing stuff like quoting CTCP messages
+* Make it possible to use Scheme functions in the Parser itself
 
 Networking:
+* Add hooks for DCC CHAT?
 * Add a networked interface to guile repl
    - Admins only
-   - 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
 
 Documentation:
 * Work on Texinfo manual (especially scripting section)
index 6c352c9..eec3c07 100644 (file)
@@ -159,14 +159,16 @@ twenty (20). `min-level' is one of the *Note Scheme User Levels::. A
 user must be at least a `min-level' user to use the new command. None
 of the arguments are guaranteed to be passed; if they aren't they are
 set to the empty string `""'. An example of a new command would be:
-(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)
+     (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)
 
-   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'.
 
 \1f
 File: bobot++.info,  Node: Hooks,  Next: Scheme User Levels,  Prev: Adding New Commands,  Up: Scripting
@@ -204,11 +206,11 @@ is prototyped as `(bot:addhook type regex function pri fall name)'.
 *Note Hook Types::). `regex' is a standard regular expression. If
 `regex' is matched, `function' will be called. `function' will take a
 different number of args depending on the hook type. `pri' specifies
-the priority of the hook---higher priority hooks are executed first.
+the priority of the hook--higher priority hooks are executed first.
 This argument is optional and defaults to `0'. `fall' is `#t' if the
 hook is a fallthrough hook and `#f' is the hook is not a fallthrough
 hook. This arg is also optional and default to `#t'. `name' is the
-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
 name then you can have more than one hook that matches the same regexp,
 as long as they have the same name. E.g. in a log script you could have
 the regexps for the log function all be `".*"' and set their names to
@@ -226,22 +228,31 @@ general format of a hook is:
    * `hooks/name' (this is the Scheme variable name of the hook)
         - Description of the hook
 
-        - # of args
-             - `arg1': desc
+        - ARG1 ARG2 ... ARGN
+             - ARG1: desc
 
-             - `arg2': desc
+             - ARG2: desc
 
              - ...
 
-             - `argN': desc
+             - ARGN: desc
 
    That said, here is the list of available hooks: FIXME: write docs
 
    * `hooks/action'
-        - Description of the hook
+        - This hook is triggered when someone performs an action.
 
-        - # 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"'.
 
    * `hooks/nickname'
         - Description of the hook
@@ -396,19 +407,19 @@ use the lower level functions.
 \1f
 File: bobot++.info,  Node: High Level Message Functions,  Next: Low Level Message Functions,  Prev: Sending Messages,  Up: Sending Messages
 
-``High Level'' Message Functions
---------------------------------
+"High Level" Message Functions
+------------------------------
 
    ...
 
 \1f
 File: bobot++.info,  Node: Low Level Message Functions,  Prev: High Level Message Functions,  Up: Sending Messages
 
-``Low Level'' Message Functions
--------------------------------
+"Low Level" Message Functions
+-----------------------------
 
-   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
 before using these. If you have no idea what these do, read rfc 2812
 (IRC Client Protocol) and CTCP spec. These functions all return
 `*unspecified*' always, so don't use the return value for anything.
@@ -432,32 +443,6 @@ might want to know.
 bot:exit-hook THUNK' where THUNK is an argumentless procedure (a
 thunk). When the bot exits your thunk will be called.
 
-   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.
-
 \1f
 File: bobot++.info,  Node: Concept Index,  Next: Function Index,  Prev: Scripting,  Up: Top
 
@@ -487,6 +472,7 @@ Variable Index
 
 * Menu:
 
+* exit-hook:                             Misc Scripting Stuff.
 * hooks/action:                          Hook Types.
 * hooks/ctcp:                            Hook Types.
 * hooks/ctcp-reply:                      Hook Types.
@@ -524,16 +510,16 @@ Node: Using the Bot\7f2499
 Node: User Levels\7f2673
 Node: Scripting\7f3677
 Node: Adding New Commands\7f4585
-Node: Hooks\7f5828
-Node: Creating a Hook\7f6766
-Node: Hook Types\7f7908
-Node: Scheme User Levels\7f10381
-Node: Sending Messages\7f11510
-Node: High Level Message Functions\7f12107
-Node: Low Level Message Functions\7f12325
-Node: Misc Scripting Stuff\7f13084
-Node: Concept Index\7f14710
-Node: Function Index\7f14892
-Node: Variable Index\7f15153
+Node: Hooks\7f5852
+Node: Creating a Hook\7f6790
+Node: Hook Types\7f7929
+Node: Scheme User Levels\7f10869
+Node: Sending Messages\7f11998
+Node: High Level Message Functions\7f12595
+Node: Low Level Message Functions\7f12809
+Node: Misc Scripting Stuff\7f13562
+Node: Concept Index\7f13981
+Node: Function Index\7f14163
+Node: Variable Index\7f14424
 \1f
 End Tag Table
index 56bbf55..1dae231 100644 (file)
@@ -167,14 +167,16 @@ will take and must be within zero (0) and twenty
 at least a @code{min-level} user to use the new command. None of the
 arguments are guaranteed to be passed; if they aren't they are set to
 the empty string @code{""}. An example of a new command would be:
-@verb{|
+
+@example
 (define (hello channel name)
-  (if (string=? name "")}@*
+  (if (string=? name "")
     (bot:say channel "Hello world!")
     (bot:say channel (string-append "Hello " name "!")))
 
 (bot:addcommand "hello" hello #t 2 0)
-|}
+@end example
+
 This will display ``Hello World!'' if called as @kbd{!hello} and
 ``Hello World @code{USER}'' if called as @kbd{!hello @var{USER}}. 
 
@@ -183,17 +185,18 @@ This will display ``Hello World!'' if called as @kbd{!hello} and
 
 @cindex Background on Hooks
 Hooks are a powerful feature of Bobot++. Hooks are a hybrid of ircII
-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.
 
 @menu
 * Creating a Hook::             
@@ -236,16 +239,16 @@ format of a hook is:
 @item
 Description of the hook
 @item
-# of args
+@var{arg1} @var{arg2} ... @var{argn}
 @itemize @minus
 @item
-@code{arg1}: desc
+@var{arg1}: desc
 @item
-@code{arg2}: desc
+@var{arg2}: desc
 @item
 ...
 @item
-@code{argN}: desc
+@var{argN}: desc
 @end itemize
 @end itemize
 @end itemize
@@ -260,12 +263,21 @@ FIXME: write docs
 @code{hooks/action}
 @itemize @minus
 @item
-Description of the hook
+This hook is triggered when someone performs an action.
 @item
-# of args
+@var{from}, @var{to}, @var{action}
 @itemize @minus
 @item
-@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"}.
 @end itemize
 @end itemize
 
@@ -595,40 +607,41 @@ command. Make sure to @code{bot:ctcp-quote} the message!
 These are a few useful things that I thought people writing scripts
 might want to know.
 
+@vindex exit-hook
 If you want to execute code when the bot exits, just do
 @code{add-hook! bot:exit-hook @var{thunk}} where @var{thunk} is an
 argumentless procedure (a thunk). When the bot exits your thunk will
 be called.
 
-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. 
-
-@example
-(bot:addhook hooks/public "foo"
-             (lambda (f t p)
-               (not-from-me f ((bot:say t "foo to the what!")))))
-@end example
-
-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:
-
-@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
-
-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 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. 
+
+@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
+
+@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:
+
+@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
+
+@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.
 
 @node Concept Index, Function Index, Scripting, Top
 @unnumbered Concept Index
index ec98068..bbddcd3 100644 (file)
@@ -136,8 +136,6 @@ Bot::Bot(String filename, bool debug_on)
 
 Bot::~Bot()
 {
-  // TODO: is it ok to delete iterators!?!
-
   Person *p;
   while (spyList.size() != 0) {
     p = (*spyList.begin()).second;
@@ -524,7 +522,7 @@ Bot::connect(int serverNumber)
 void
 Bot::addDCC(Person * from, unsigned long address, int port)
 {
-  DCCConnection * d = new DCCConnection(this, from->getAddress(),
+  DCCConnection * d = new DCCConnection(this, from->getAddress (),
                                         address, port);
 
   if (!d->connect())
@@ -532,14 +530,15 @@ Bot::addDCC(Person * from, unsigned long address, int port)
       logLine ("DCC Connection failed from " + from->getAddress ());
       return;
     }
-  logLine ("DCC Connection worked!");
+  logLine ("DCC CHAT accepted from" + from->getAddress ());
   dccConnections.push_back(d);
 }
 
 void
 Bot::rehash()
 {
-  for (std::map<String, Channel *, std::less<String> >::iterator it = channelList->begin();
+  for (std::map<String, Channel *, std::less<String> >::iterator it = 
+        channelList->begin();
        it != channelList->end(); ++it)
     serverConnection->queue->sendWho((*it).first);
 }
index f5ff1e5..ff01019 100644 (file)
@@ -63,7 +63,9 @@ struct Hook {
     ACTION, NICKNAME, SIGNOFF, CTCP, CTCP_REPLY,
     DISCONNECT, FLOOD, INVITE, JOIN, KICK, LEAVE,
     MODE, MESSAGE, NAMES, NOTICE, PUBLIC,
-    PUBLIC_NOTICE, RAW, TIMER, TOPIC
+    PUBLIC_NOTICE, RAW, TIMER, TOPIC,
+    // send hooks
+    SEND_ACTION, SEND_CTCP, SEND_PUBLIC, SEND_MESSAGE
   };  
 };
 
index 283b52a..a708aaf 100644 (file)
@@ -22,7 +22,8 @@
 #include "DCCParser.H"
 #include "DCCConnection.H"
 
-DCCConnection::DCCConnection(Bot *b, String n, unsigned long address, int port)
+DCCConnection::DCCConnection(Bot *b, String n, unsigned long address, 
+                            int port)
  : Connection(address, port), bot(b), nuh(n),
    lastSpoken(time(0)), autoRemove(true)
 { }
@@ -32,7 +33,6 @@ DCCConnection::connect()
 {
   if (!socket.connect())
     return false;
-
   return true;
 }
 
index 15c1b2a..b869e37 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "Connection.H"
 #include "Bot.H"
+#include "DCCPerson.H"
 
 class DCCPerson;
 class UserCommands;
index e8e2075..6604197 100644 (file)
@@ -1,5 +1,6 @@
 // DCCParser.C  -*- C++ -*-
 // Copyright (c) 1998 Etienne BERNARD
+// Copyright (C) 2002 Clinton Ebadi
 
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
index dbd06cd..b41bae9 100644 (file)
@@ -1,5 +1,6 @@
 // DCCPerson.C  -*- C++ -*-
 // Copyright (c) 1998 Etienne BERNARD
+// Copyright (C) 2002 Clinton Ebadi
 
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
index c00041c..3ea9947 100644 (file)
@@ -85,6 +85,10 @@ Interp::Startup()
   scm_c_define ("hooks/raw", scm_long2num(Hook::RAW));
   scm_c_define ("hooks/timer", scm_long2num(Hook::TIMER));
   scm_c_define ("hooks/topic", scm_long2num(Hook::TOPIC));
+  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));
 
 
   // procedures
index d62ef0b..bb51b54 100644 (file)
@@ -71,20 +71,14 @@ void print_version ()
 }
 void print_short_help (const char *name)
 {
-  std::cerr << "Usage: " << name << " [--help] [--version] [--no-background]\n\t"
+  std::cerr << "Usage: " 
+           << name 
+           << " [--help] [--version] [--no-background]\n\t"
            << "[--config-file file] [--config-dir dir] [--debug]\n\t"
            << "[--config dir-under-configpath]\n\t"
            << "[--sys-config dir-in-sysconfdir]\n\t"
            << "[--user-config dir-userdir] [--debug]\n"
            << "\n--help shows long help.\n";
-  /*    " -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";
-  */
 }
 
 void print_long_help (const char *name)
index 7cbb766..9be4f08 100644 (file)
@@ -91,12 +91,7 @@ Parser::parseLine (ServerConnection * cnx, String line)
 
   String command = st.nextToken ();
   String rest = st.rest ();
-  /*  for (int i = 0; functions[i].name != 0; i++)
-     if (command == functions[i].name) {
-     functions[i].function(cnx, from, rest);
-     break;
-     }
-   */
+
   if (fptr temp_func = functions[command])
     temp_func (cnx, from, rest);
   delete from;
@@ -855,7 +850,7 @@ Parser::parseCTCP (ServerConnection * cnx,
          // FIXME: debug DCC
          st2.nextToken ();
          unsigned long address =
-           ntohl (strtoul ((const char *) st2.nextToken (), 0, 0));
+           strtoul ((const char *) st2.nextToken (), 0, 0);
          int port = atoi ((const char *) st2.nextToken ());
          if (port >= 1024 && Utils::getLevel (cnx->bot, from->getAddress ()))
            cnx->bot->addDCC (from, address, port);
index 9007de8..502eaf6 100644 (file)
 #include <map>
 #include <string>
 
-// 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
+//   }
 // };
 
 class userFunction {
@@ -123,7 +153,6 @@ public:
   static void sendNotice(Person *, String);
 private:
   
-  typedef void (*fptr)(ServerConnection *, Person *, String);
   static std::map<std::string, fptr, std::less<std::string> > functions;
   
 };
index e04fb0e..d63ac4f 100644 (file)
@@ -91,16 +91,12 @@ ServerQueue::sendCTCP(String to, String command,
                       String message)
 {
   sendPrivmsg(to, String("\001") + command + " " + message + "\001");
-  // hook stuff (only get action for now)
 
-  // I don't think it is useful to generate messages for other types
-  // of CTCP stuff.
-  puts (command);
 #ifdef USESCRIPTS
   if (command == "ACTION")
     {
-      Interp::bot->botInterp->RunHooks (Hook::ACTION,
-                                       MNICK+ " " + to +
+      Interp::bot->botInterp->RunHooks (Hook::SEND_ACTION,
+                                       MNICK + " " + to +
                                        " " + message,
                                        scm_listify (Utils::
                                                  string2SCM (MNICK),
@@ -110,6 +106,20 @@ ServerQueue::sendCTCP(String to, String command,
                                                  string2SCM (message),
                                                  SCM_UNDEFINED));
     }
+  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));
 #endif
 
 }
@@ -212,7 +222,7 @@ ServerQueue::sendPrivmsg(String dest, String message)
 #ifdef USESCRIPTS
   if (message[0] != '\001')
     if (Utils::isChannel (dest))
-      Interp::bot->botInterp->RunHooks (Hook::PUBLIC,
+      Interp::bot->botInterp->RunHooks (Hook::SEND_PUBLIC,
                                        Interp::bot->nickName + " " + dest +
                                        " " + message,
                                        scm_listify (Utils::
@@ -223,7 +233,7 @@ ServerQueue::sendPrivmsg(String dest, String message)
                                                     string2SCM
                                                     (message), SCM_UNDEFINED));
     else
-      Interp::bot->botInterp->RunHooks (Hook::MESSAGE,
+      Interp::bot->botInterp->RunHooks (Hook::SEND_MESSAGE,
                                        Interp::bot->nickName + " " +
                                        message,
                                        scm_listify (Utils::
index 8a414a1..235df93 100644 (file)
@@ -80,7 +80,8 @@ UserList::save()
   if (!file)
     return;
 
-  ++it; // We skip the bot's entry
+  // FIXME: fix bug (see BUGS) and inc once
+  ++it; ++it; // We skip the bot's entry
   for ( ; it != l.end(); ++it)
     if ((*it)->isStillValid()) {
       file << (*it)->mask.getMask() << ":"