[project @ 2004-04-28 03:33:52 by unknown_lamer]
[clinton/bobotpp.git] / source / Bot.C
index 331b349..5b59b4c 100644 (file)
@@ -1,6 +1,6 @@
 // Bot.C  -*- C++ -*-
 // Copyright (c) 1997, 1998 Etienne BERNARD
-// Copyright (C) 2002 Clinton Ebadi
+// Copyright (C) 2002,2003 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
@@ -17,6 +17,7 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
 
 #include <fstream>
+#include <algorithm>
 #include <iomanip>
 #include <cstring>
 #include <cstdlib>
 
 #include "Bot.H"
 #include "DCCConnection.H"
+#include "DCCChatConnection.H"
 #include "StringTokenizer.H"
 #include "ServerConnection.H"
 #include "Utils.H"
 #include "UserCommands.H"
+#include "DCCManager.H"
+
+
+unsigned int Bot::MAX_MESSAGES = 2;
 
 #define DEFAULT_NICKNAME "Bobot"
 #define DEFAULT_USERNAME "bobot"
@@ -82,20 +88,17 @@ Bot::Bot(String filename, bool debug_on)
 
   init_user_functions ();
 
-#if HAVE_IOSBASE
-  logFile.open(logs_dir + logFileName, std::ios_base::out | 
-              std::ios_base::ate | std::ios_base::app);
-#else
- logFile.open(logs_dir + logFileName, ios::out | ios::ate 
-             | ios::app);
-#endif
-  logLine("Starting log.");
+  set_log_dir (logs_dir);
+  set_log_file (logFileName);
+
+
   channelList = new ChannelList();
   serverList = new ServerList();
   readConfig();
   userList = new UserList(userListFileName);
   shitList = new ShitList(shitListFileName);
   todoList = new TodoList();
+  dccConnections = new DCCManager ();
 
   // Let's read the alias file
   std::ifstream initFile(initFileName);
@@ -120,11 +123,11 @@ Bot::Bot(String filename, bool debug_on)
       if (!userFunctions[alias])
        {
          if (userFunction *u = userFunctions[command])
-           userFunctions[alias] = 
-             new
-             userFunction(u->function,
-                          u->minLevel,
-                          u->needsChannelName);
+           userFunctions[alias] = 
+             new
+             userFunction(u->function,
+                          u->minLevel,
+                          u->needsChannelName);
        }
     }
   }
@@ -139,21 +142,13 @@ 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;
     spyList.erase(spyList.begin());
     delete p;
   }
-  DCCConnection *d;
-  while (dccConnections.size() != 0) {
-    d = *dccConnections.begin();
-    dccConnections.erase(dccConnections.begin());
-    delete d;
-  }
-
+  delete dccConnections;
   destroy_user_functions ();
 
   wantedChannel *w;
@@ -249,7 +244,18 @@ Bot::readConfig()
       }
     }
     else if (command == "LOGFILE")
-       logFileName = parameters;
+      {
+       if (parameters != logFileName)
+         {
+           if (parameters[0] == '/')
+             {
+               set_log_dir ("/");
+               set_log_file (parameters.subString (1));
+             }
+           else
+             set_log_file (parameters);
+         }
+      }
 #ifdef USESCRIPTS
     else if (command == "SCRIPTLOGFILE")
       scriptLogFileName = parameters;
@@ -292,6 +298,7 @@ Bot::run()
 
   while (!stop) {
     waitForInput();  // This is the main event loop
+    dccConnections->checkStale ();
     if (!serverConnection->queue->flush())
       nextServer();
   }
@@ -317,9 +324,10 @@ Bot::waitForInput()
   FD_SET(sock, &rd);
 #endif
 
-  for (std::list<DCCConnection *>::iterator it = dccConnections.begin();
-       it != dccConnections.end(); ++it) {
-    int s = (*it)->getFileDescriptor();
+  DCC_MAP* dccmap = &dccConnections->dcc_map;
+  for (DCC_MAP::iterator it = dccmap->begin ();
+       it != dccmap->end(); ++it) {
+    int s = it->second->dcc->getFileDescriptor();
 #ifdef _HPUX_SOURCE
     rd |= s;
 #else
@@ -346,27 +354,29 @@ Bot::waitForInput()
       if (serverConnection->handleInput())
         nextServer();
 
-    std::list<DCCConnection *>::iterator it = dccConnections.begin();
-    std::list<DCCConnection *>::iterator it2;
-
-    while (it != dccConnections.end()) {
-      it2 = it;
-      ++it;
-#ifdef _HPUX_SOURCE
-      if (rd & (*it2)->getFileDescriptor()) {
-#else
-      if (FD_ISSET((*it2)->getFileDescriptor(), &rd)) {
-#endif
-        if ((*it2)->handleInput()) {
-          delete *it2;
-          dccConnections.erase(it2);
-        }
-      }
-    }
+//     std::list<DCCConnection *>::iterator it = dccConnections.begin();
+//     std::list<DCCConnection *>::iterator it2;
+
+//     while (it != dccConnections.end()) {
+//       it2 = it;
+//       ++it;
+// #ifdef _HPUX_SOURCE
+//       if (rd & (*it2)->getFileDescriptor()) {
+// #else
+//      if (FD_ISSET((*it2)->getFileDescriptor(), &rd)) {
+// #endif
+//         if ((*it2)->handleInput()) {
+//           delete *it2;
+//           dccConnections.erase(it2);
+//         }
+//       }
+//     }
+//     }
+    dccConnections->checkInput (rd);
   }
 
-  if (currentTime < std::time(NULL)) { // Actions that we do each second
-    currentTime = std::time(NULL);
+  if (currentTime < std::time(0)) { // Actions that we do each second
+    currentTime = std::time(0);
     for (std::map<String, unsigned int, std::less<String> >::iterator
            it = ignoredUserhosts.begin();
          it != ignoredUserhosts.end(); ++it)
@@ -379,16 +389,16 @@ Bot::waitForInput()
     }
 #ifdef USESCRIPTS
     botInterp->RunTimers(currentTime);
-#endif
 
-#ifdef USESCRIPTS
     tm *thisTime = localtime(&currentTime);
-    if (thisTime->tm_sec == 0) {
-      char s[6];
-      sprintf(s, "%2d:%2d", thisTime->tm_hour, thisTime->tm_min);
-      botInterp->RunHooks(Hook::TIMER, String(s),
-                          gh_list(Utils::string2SCM(String(s)), SCM_UNDEFINED));
-    }
+    if (thisTime->tm_sec == 0)
+      {
+       char s[6];
+       std::sprintf(s, "%2d:%2d", thisTime->tm_hour, thisTime->tm_min);
+       botInterp->RunHooks(Hook::TIMER, String(s),
+                           gh_list(Utils::string2SCM(String(s)), 
+                                   SCM_UNDEFINED));
+      }
 #endif
 
   }
@@ -408,17 +418,17 @@ Bot::waitForInput()
          serverConnection->queue->sendJoin((*it).first, (*it).second->key);
   }
 
-  std::list<DCCConnection *>::iterator it2;
+//   std::list<DCCConnection *>::iterator it2;
 
-  for (std::list<DCCConnection *>::iterator it = dccConnections.begin();
-       it != dccConnections.end(); ) {
-    it2 = it;
-    ++it;
-    if ((*it2)->autoRemove && currentTime >= (std::time_t)((*it2)->lastSpoken + Bot::DCC_DELAY)) {
-      delete *it2;
-      dccConnections.erase(it2);
-    }
-  }
+//   for (std::list<DCCConnection *>::iterator it = dccConnections.begin();
+//        it != dccConnections.end(); ) {
+//     it2 = it;
+//     ++it;
+//     if ((*it2)->autoRemove && currentTime >= (std::time_t)((*it2)->lastSpoken + Bot::DCC_DELAY)) {
+//       delete *it2;
+//       dccConnections.erase(it2);
+//     }
+//   }
 
   if (currentTime >= (std::time_t)(serverConnection->serverLastSpoken + Bot::PING_TIME) && !sentPing) {
     serverConnection->queue->sendPing("Testing connection");
@@ -514,21 +524,30 @@ Bot::connect(int serverNumber)
 }
 
 void
-Bot::addDCC(Person * from, unsigned long address, int port)
+Bot::addDCC(Person * from, unsigned long address, int port, int type)
 {
-  DCCConnection * d = new DCCConnection(this, from->getAddress(),
-                                        address, port);
+  DCCConnection *d = 0;
 
-  if (!d->connect())
+  if (type == CHAT)
+    d = new DCCChatConnection(this, from->getAddress (),
+                             address, port);
+  else
     return;
 
-  dccConnections.push_back(d);
+  if (!d->connect())
+    {
+      logLine ("DCC Connection failed from " + from->getAddress ());
+      return;
+    }
+  logLine ("DCC CHAT accepted from" + from->getAddress ());
+  dccConnections->addConnection (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);
 }
@@ -633,6 +652,8 @@ Bot::init_user_functions ()
   userFunctions["SERVER"] = uf (UserCommands::Server, User::FRIEND, false);
   userFunctions["SERVERLIST"] =
     uf (UserCommands::ServerList, User::FRIEND, false);
+  userFunctions["SETFLOODRATE"] =
+    uf (UserCommands::SetFloodRate, User::MASTER, false);
   userFunctions["SETVERSION"] =
     uf (UserCommands::SetVersion, User::MASTER, false);
   userFunctions["SHITLIST"] =
@@ -663,9 +684,32 @@ namespace
 void
 Bot::destroy_user_functions ()
 {
-  for_each (userFunctions.begin (),
+  std::for_each (userFunctions.begin (),
            userFunctions.end (),
            erase_userf);
   userFunctions.erase (userFunctions.begin (),
                       userFunctions.end ());
 }
+
+void
+Bot::set_log_file (String name)
+{
+  logFileName = name;
+  logFile.close ();
+  logFile.clear ();
+#if HAVE_IOSBASE
+  logFile.open(logs_dir + logFileName, std::ios_base::out | 
+              std::ios_base::ate | std::ios_base::app);
+#else
+  logFile.open(logs_dir + logFileName, ios::out | ios::ate 
+             | ios::app);
+#endif
+
+  logLine("Starting log.");
+}
+
+void
+Bot::set_log_dir (String dir)
+{
+  logs_dir = dir;
+}