فهرست منبع

Refactored to render and input.

Render handles outputting parsed IRC messages.
Input handle the input, and user commands.
Steve Thielemann 3 سال پیش
والد
کامیت
556127e647
7فایلهای تغییر یافته به همراه416 افزوده شده و 370 حذف شده
  1. 1 1
      CMakeLists.txt
  2. 269 0
      input.cpp
  3. 16 0
      input.h
  4. 0 29
      irc.cpp
  5. 21 340
      main.cpp
  6. 98 0
      render.cpp
  7. 11 0
      render.h

+ 1 - 1
CMakeLists.txt

@@ -56,6 +56,6 @@ endif()
 
 add_subdirectory(yaml-cpp)
 
-add_executable(irc-door main.cpp irc.h irc.cpp)
+add_executable(irc-door main.cpp irc.h irc.cpp render.h render.cpp input.h input.cpp)
 target_link_libraries(irc-door door++ pthread ${LINK_LIBS} dl yaml-cpp)
 

+ 269 - 0
input.cpp

@@ -0,0 +1,269 @@
+#include "input.h"
+
+bool allow_part = false;
+bool allow_join = false;
+
+const int ms_input_delay = 50;
+std::string input;
+std::string prompt; // mostly for length to erase/restore properly
+int max_input = 100;
+door::ANSIColor prompt_color{door::COLOR::YELLOW, door::COLOR::BLUE,
+                             door::ATTR::BOLD};
+door::ANSIColor input_color{door::COLOR::WHITE}; // , door::COLOR::BLUE};
+
+void erase(door::Door &d, int count) {
+  d << door::reset;
+  for (int x = 0; x < count; ++x) {
+    d << "\x08 \x08";
+  }
+}
+
+void clear_input(door::Door &d) {
+  if (prompt.empty())
+    return;
+  erase(d, input.size());
+  erase(d, prompt.size() + 1);
+}
+
+void restore_input(door::Door &d) {
+  if (prompt.empty())
+    return;
+  d << prompt_color << prompt << input_color << " " << input;
+}
+
+/*
+commands:
+
+/h /help /?
+/t /talk /talkto [TARGET]
+/msg [TO] [message]
+/me [message]
+/quit [message, maybe]
+/join [TARGET]
+/part [TARGET]
+
+future:
+/list    ?
+/version ?
+*/
+
+void parse_input(door::Door &door, ircClient &irc) {
+  // yes, we have something
+  if (input[0] == '/') {
+    // command given
+    std::vector<std::string> cmd = split_limit(input, 3);
+
+    if (cmd[0] == "/quit") {
+      irc.write("QUIT");
+    }
+    if (cmd[0] == "/talkto") {
+      irc.talkto(cmd[1]);
+      door << "[talkto = " << cmd[1] << "]" << door::nl;
+    }
+
+    if (cmd[0] == "/join") {
+      if (allow_join) {
+        std::string tmp = "JOIN " + cmd[1];
+        irc.write(tmp);
+      }
+    }
+
+    if (cmd[0] == "/part") {
+      if (allow_part) {
+        std::string tmp = "PART " + cmd[1];
+        irc.write(tmp);
+      }
+    }
+
+    if (cmd[0] == "/me") {
+      cmd = split_limit(input, 2);
+      std::string tmp =
+          "PRIVMSG " + irc.talkto() + " :\x01" + "ACTION " + cmd[1] + "\x01";
+      irc.write(tmp);
+      door << "* " << irc.nick << " " << cmd[1] << door::nl;
+    }
+
+    if (cmd[0] == "/info") {
+      irc.channels_lock.lock();
+      for (auto c : irc.channels) {
+        door << "CH " << c.first << " ";
+        for (auto s : c.second) {
+          door << s << " ";
+        }
+        door << door::nl;
+      }
+      irc.channels_lock.unlock();
+    }
+
+  } else {
+    std::string target = irc.talkto();
+    std::string output = "PRIVMSG " + target + " :" + input;
+    // I need to display something here to show we've said something (and
+    // where we've said it)
+    door::ANSIColor nick_color{door::COLOR::WHITE, door::COLOR::BLUE};
+
+    if (target[0] == '#') {
+      door::ANSIColor channel_color = door::ANSIColor{
+          door::COLOR::YELLOW, door::COLOR::BLUE, door::ATTR::BOLD};
+
+      door << nick_color << irc.nick << door::ANSIColor(door::COLOR::CYAN)
+           << "/" << channel_color << target << door::reset << " " << input
+           << door::nl;
+
+    } else {
+      door << nick_color << irc.nick << "/" << target << door::reset << " "
+           << input << door::nl;
+    }
+    irc.write(output);
+  }
+
+  input.clear();
+}
+
+const char *hot_keys[] = {"/join #", "/part #", "/talkto ", "/help", "/quit "};
+
+bool check_for_input(door::Door &door, ircClient &irc) {
+  int c;
+
+  // return true when we have input and is "valid" // ready
+  if (prompt.empty()) {
+    // ok, nothing has been displayed at this time.
+    if (door.haskey()) {
+      // something to do.
+      prompt = "[" + irc.talkto() + "]";
+      door << prompt_color << prompt << input_color << " ";
+      c = door.sleep_key(1);
+      if (c < 0) {
+        // handle timeout/hangup/out of time
+        return false;
+      }
+      if (c > 0x1000)
+        return false;
+      if (isprint(c)) {
+        door << (char)c;
+        input.append(1, c);
+      }
+    }
+    return false;
+  } else {
+    // continue on with what we have displayed.
+    c = door.sleep_ms_key(ms_input_delay);
+    if (c != -1) {
+      /*
+      c = door.sleep_key(1);
+      if (c < 0) {
+        // handle error
+        return false;
+      }
+      */
+      if (c > 0x1000)
+        return false;
+      if (isprint(c)) {
+        door << (char)c;
+        input.append(1, c);
+        // hot-keys
+        if (input[0] == '/') {
+          if (input.size() == 2) {
+            char c = std::tolower(input[1]);
+
+            if (!allow_part) {
+              if (c == 'p')
+                c = '!';
+            }
+            if (!allow_join) {
+              if (c == 'j')
+                c = '!';
+            }
+
+            for (auto hk : hot_keys) {
+              if (c == hk[1]) {
+                erase(door, input.size());
+                input = hk;
+                door << input;
+                break;
+              }
+            }
+            /*
+          switch (input[1]) {
+          case 'j':
+          case 'J':
+            erase(door, input.size());
+            input = "/join ";
+            door << input;
+            break;
+          case 'p':
+          case 'P':
+            erase(door, input.size());
+            input = "/part ";
+            door << input;
+            break;
+          case 't':
+          case 'T':
+            erase(door, input.size());
+            input = "/talkto ";
+            door << input;
+            break;
+          case 'h':
+          case 'H':
+          case '?':
+            erase(door, input.size());
+            input = "/help";
+            door << input;
+            break;
+          case 'q':
+          case 'Q':
+            erase(door, input.size());
+            input = "/quit ";
+            door << input;
+          }
+          */
+          }
+        }
+      }
+      if ((c == 0x08) or (c == 0x7f)) {
+        // hot-keys
+        if (input[0] == '/') {
+          for (auto hk : hot_keys) {
+            if (input == hk) {
+              /*
+   if ((input == "/help") or (input == "/talkto ") or
+       (input == "/join ") or (input == "/part ") or
+       (input == "/quit ")) { */
+              clear_input(door);
+              /*
+                 erase(door, input.size());
+                 erase(door, prompt.size());
+              */
+              input.clear();
+              prompt.clear();
+              return false;
+            }
+          }
+        }
+        if (input.size() > 1) {
+          erase(door, 1);
+          door << input_color;
+          input.erase(input.length() - 1);
+        } else {
+          // erasing the last character
+          erase(door, 1);
+          input.clear();
+          erase(door, prompt.size() + 1);
+          prompt.clear();
+          return false;
+        }
+      }
+      if (c == 0x0d) {
+        clear_input(door);
+        prompt.clear();
+        /*
+        Should the input be handled/parsed here?
+
+         */
+        parse_input(door, irc);
+        return true;
+      }
+    }
+    return false;
+  }
+}

+ 16 - 0
input.h

@@ -0,0 +1,16 @@
+#ifndef INPUT_H
+#define INPUT_H
+
+#include "door.h"
+#include "irc.h"
+
+extern bool allow_part;
+extern bool allow_join;
+
+void clear_input(door::Door &d);
+void restore_input(door::Door &d);
+void parse_input(door::Door &door, ircClient &irc);
+
+bool check_for_input(door::Door &d, ircClient &irc);
+
+#endif

+ 0 - 29
irc.cpp

@@ -496,26 +496,6 @@ void ircClient::receive(std::string &text) {
     }
   }
 
-  /*
-    if (parts[1] == "JOIN") {
-      // Are we joining?
-      std::string guest = parse_nick(parts[0]);
-      if (guest == nick) {
-        // yes, it is us!
-        std::string temp = parts[2];
-        temp.erase(0, 1);
-        talkto = temp;
-        std::string msg = "You have joined " + temp;
-        message(msg);
-      } else {
-        std::string temp = parts[2];
-        temp.erase(0, 1);
-        std::string msg = parse_nick(parts[0]) + " has joined " + temp;
-        message(msg);
-      }
-    }
-  */
-
   // CTCP handler
   // NOTE:  When sent to a channel, the response is sent to the sender.
 
@@ -539,15 +519,6 @@ void ircClient::receive(std::string &text) {
       }
     }
 
-    /*
-        if (parts[1] == "372") {
-          // MOTD
-          std::string msg = parts[3];
-          msg.erase(0, 1);
-          motd.push_back(msg);
-        }
-    */
-
     if ((parts[1] == "376") or (parts[1] == "422")) {
       // END MOTD, or MOTD MISSING
       registered = true;

+ 21 - 340
main.cpp

@@ -5,7 +5,9 @@
 #include <thread> // sleep_for
 
 #include "door.h"
+#include "input.h"
 #include "irc.h"
+#include "render.h"
 #include "yaml-cpp/yaml.h"
 
 #include <boost/asio.hpp>
@@ -19,162 +21,6 @@ bool file_exists(const std::string name) {
   return f.good();
 }
 
-const int ms_input_delay = 50;
-std::string input;
-std::string prompt; // mostly for length to erase/restore properly
-int max_input = 100;
-door::ANSIColor prompt_color{door::COLOR::YELLOW, door::COLOR::BLUE,
-                             door::ATTR::BOLD};
-door::ANSIColor input_color{door::COLOR::WHITE}; // , door::COLOR::BLUE};
-
-void erase(door::Door &d, int count) {
-  d << door::reset;
-  for (int x = 0; x < count; ++x) {
-    d << "\x08 \x08";
-  }
-}
-
-void clear_input(door::Door &d) {
-  if (prompt.empty())
-    return;
-  erase(d, input.size());
-  erase(d, prompt.size() + 1);
-}
-
-void restore_input(door::Door &d) {
-  if (prompt.empty())
-    return;
-  d << prompt_color << prompt << input_color << " " << input;
-}
-
-/*
-commands:
-
-/h /help /?
-/t /talk /talkto [TARGET]
-/msg [TO] [message]
-/me [message]
-/quit [message, maybe]
-/join [TARGET]
-/part [TARGET]
-
-future:
-/list    ?
-/version ?
-*/
-
-bool check_for_input(door::Door &d, ircClient &irc) {
-  int c;
-
-  // return true when we have input and is "valid" // ready
-  if (prompt.empty()) {
-    // ok, nothing has been displayed at this time.
-    if (d.haskey()) {
-      // something to do.
-      prompt = "[" + irc.talkto() + "]";
-      d << prompt_color << prompt << input_color << " ";
-      c = d.sleep_key(1);
-      if (c < 0) {
-        // handle timeout/hangup/out of time
-        return false;
-      }
-      if (c > 0x1000)
-        return false;
-      if (isprint(c)) {
-        d << (char)c;
-        input.append(1, c);
-      }
-    }
-    return false;
-  } else {
-    // continue on with what we have displayed.
-    c = d.sleep_ms_key(ms_input_delay);
-    if (c != -1) {
-      /*
-      c = d.sleep_key(1);
-      if (c < 0) {
-        // handle error
-        return false;
-      }
-      */
-      if (c > 0x1000)
-        return false;
-      if (isprint(c)) {
-        d << (char)c;
-        input.append(1, c);
-        // hot-keys
-        if (input[0] == '/') {
-          if (input.size() == 2) {
-            switch (input[1]) {
-            case 'j':
-            case 'J':
-              erase(d, input.size());
-              input = "/join ";
-              d << input;
-              break;
-            case 'p':
-            case 'P':
-              erase(d, input.size());
-              input = "/part ";
-              d << input;
-              break;
-            case 't':
-            case 'T':
-              erase(d, input.size());
-              input = "/talkto ";
-              d << input;
-              break;
-            case 'h':
-            case 'H':
-            case '?':
-              erase(d, input.size());
-              input = "/help";
-              d << input;
-              break;
-            case 'q':
-            case 'Q':
-              erase(d, input.size());
-              input = "/quit";
-              d << input;
-            }
-          }
-        }
-      }
-      if ((c == 0x08) or (c == 0x7f)) {
-        // hot-keys
-        if (input[0] == '/') {
-          if ((input == "/help") or (input == "/talkto ") or
-              (input == "/join ") or (input == "/part") or (input == "/quit")) {
-            erase(d, input.size());
-            erase(d, prompt.size());
-            input.clear();
-            prompt.clear();
-            return false;
-          }
-        }
-        if (input.size() > 1) {
-          erase(d, 1);
-          d << input_color;
-          input.erase(input.length() - 1);
-        } else {
-          // erasing the last character
-          erase(d, 1);
-          input.clear();
-          erase(d, prompt.size() + 1);
-          prompt.clear();
-          return false;
-        }
-      }
-      if (c == 0x0d) {
-        clear_input(d);
-        prompt.clear();
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
 int main(int argc, char *argv[]) {
   using namespace std::chrono_literals;
 
@@ -200,6 +46,11 @@ int main(int argc, char *argv[]) {
     update_config = true;
   }
 
+  if (!config["allow_join"]) {
+    config["allow_join"] = "0";
+    update_config = true;
+  }
+
   if (!config["autojoin"]) {
     config["autojoin"] = "#bugz";
     update_config = true;
@@ -228,7 +79,16 @@ int main(int argc, char *argv[]) {
   irc.username = config["username"].as<std::string>();
   irc.autojoin = config["autojoin"].as<std::string>();
 
-  irc.debug_output = "irc.log";
+  if (config["log"]) {
+    irc.debug_output = config["log"].as<std::string>();
+    door << "irc debug logfile = " << config["log"].as<std::string>()
+         << door::nl;
+  }
+
+  if (config["allow_join"].as<int>() == 1) {
+    allow_part = true;
+    allow_join = true;
+  }
 
   irc.begin(); // start the initial request so io_context has work to do
   // boost::thread thread(boost::bind(&boost::asio::io_service::run,
@@ -240,111 +100,14 @@ int main(int argc, char *argv[]) {
 
   // main "loop" -- not the proper way to do it.
   bool in_door = true;
+
   while (in_door) {
     // the main loop
     // custom input routine goes here
 
     if (check_for_input(door, irc)) {
-      // yes, we have something
-      if (input[0] == '/') {
-        // command given
-        std::vector<std::string> cmd = split_limit(input, 3);
-
-        if (cmd[0] == "/quit") {
-          irc.write("QUIT");
-        }
-        if (cmd[0] == "/talkto") {
-          irc.talkto(cmd[1]);
-          door << "[talkto = " << cmd[1] << "]" << door::nl;
-        }
-
-        if (cmd[0] == "/join") {
-          std::string tmp = "JOIN " + cmd[1];
-          irc.write(tmp);
-        }
-
-        if (cmd[0] == "/part") {
-          std::string tmp = "PART " + cmd[1];
-          irc.write(tmp);
-        }
-
-        if (cmd[0] == "/me") {
-          cmd = split_limit(input, 2);
-          std::string tmp = "PRIVMSG " + irc.talkto() + " :\x01" + "ACTION " +
-                            cmd[1] + "\x01";
-          irc.write(tmp);
-          door << "* " << irc.nick << " " << cmd[1] << door::nl;
-        }
-
-        if (cmd[0] == "/info") {
-          irc.channels_lock.lock();
-          for (auto c : irc.channels) {
-            door << "CH " << c.first << " ";
-            for (auto s : c.second) {
-              door << s << " ";
-            }
-            door << door::nl;
-          }
-          irc.channels_lock.unlock();
-        }
-        /*
-        if (std::toupper(input[1]) == 'Q') {
-          irc.write("QUIT");
-        } else {
-          // for now, just output whatever they gave us.
-          input.erase(0, 1);
-          irc.write(input);
-        }
-        */
-      } else {
-        std::string target = irc.talkto();
-        std::string output = "PRIVMSG " + target + " :" + input;
-        // I need to display something here to show we've said something (and
-        // where we've said it)
-        door::ANSIColor nick_color{door::COLOR::WHITE, door::COLOR::BLUE};
-
-        if (target[0] == '#') {
-          door::ANSIColor channel_color = door::ANSIColor{
-              door::COLOR::YELLOW, door::COLOR::BLUE, door::ATTR::BOLD};
-
-          door << nick_color << irc.nick << door::ANSIColor(door::COLOR::CYAN)
-               << "/" << channel_color << target << door::reset << " " << input
-               << door::nl;
-
-        } else {
-          door << nick_color << irc.nick << "/" << target << door::reset << " "
-               << input << door::nl;
-        }
-        irc.write(output);
-      };
-      input.clear();
     }
 
-    /*
-    if (door.haskey()) {
-      door << ">> ";
-      std::string input = door.input_string(100);
-      door << door::nl;
-      if (!input.empty()) {
-        if (input == "/q") {
-          irc.write("QUIT :What other doors on BZ&BZ BBS work...");
-          in_door = false;
-        }
-        if (input[0] == '/') {
-          input.erase(0, 1);
-          irc.write(input);
-        } else {
-          if (irc.talkto.empty()) {
-            door << " talkto is empty?  Whaat?" << door::nl;
-          } else {
-            std::string output = "PRIVMSG " + irc.talkto + " :" + input;
-            irc.write(output);
-          }
-        }
-      }
-    }
-    */
-
     boost::optional<std::vector<std::string>> msg;
 
     // hold list of users -- until end names received.
@@ -360,92 +123,8 @@ int main(int argc, char *argv[]) {
           input_cleared = true;
           clear_input(door);
         }
-        std::vector<std::string> m = *msg;
-
-        if (m.size() == 1) {
-          // system message
-          door << "(" << m[0] << ")" << door::nl;
-          continue;
-        }
-
-        std::string cmd = m[1];
 
-        if (cmd == "366") {
-          // end of names, output and clear
-          std::string channel = split_limit(m[3], 2)[0];
-
-          irc.channels_lock.lock();
-          door << "* users on " << channel << " : ";
-          for (auto name : irc.channels[channel]) {
-            door << name << " ";
-          }
-          irc.channels_lock.unlock();
-          door << door::nl;
-          // names.clear();
-        }
-
-        if (cmd == "372") {
-          // MOTD
-          std::string temp = m[3];
-          temp.erase(0, 1);
-          door << "* " << temp << door::nl;
-        }
-
-        // 400 and 500 are errors?  should show those.
-        if ((cmd[0] == '4') or (cmd[0] == '5')) {
-          std::string tmp = m[3];
-          tmp.erase(0, 1);
-
-          door << "* " << tmp << door::nl;
-        }
-
-        if (cmd == "NOTICE") {
-          std::string tmp = m[3];
-          tmp.erase(0, 1);
-
-          door << parse_nick(m[0]) << " NOTICE " << tmp << door::nl;
-        }
-
-        if (cmd == "ACTION") {
-          if (m[2][0] == '#') {
-            door << "* " << parse_nick(m[0]) << "/" << m[2] << " " << m[3]
-                 << door::nl;
-          } else {
-            door << "* " << parse_nick(m[0]) << " " << m[3] << door::nl;
-          }
-        }
-
-        if (cmd == "TOPIC") {
-          std::string tmp = m[3];
-          tmp.erase(0, 1);
-
-          door << parse_nick(m[0]) << " set topic of " << m[2] << " to " << tmp
-               << door::nl;
-        }
-
-        if (cmd == "PRIVMSG") {
-          door::ANSIColor nick_color{door::COLOR::WHITE, door::COLOR::BLUE};
-
-          if (m[2][0] == '#') {
-            std::string tmp = m[3];
-            tmp.erase(0, 1);
-            door::ANSIColor channel_color{door::COLOR::WHITE,
-                                          door::COLOR::BLUE};
-            if (m[2] == irc.talkto()) {
-              channel_color = door::ANSIColor{
-                  door::COLOR::YELLOW, door::COLOR::BLUE, door::ATTR::BOLD};
-            }
-            door << nick_color << parse_nick(m[0])
-                 << door::ANSIColor(door::COLOR::CYAN) << "/" << channel_color
-                 << m[2] << door::reset << " " << tmp << door::nl;
-          } else {
-            std::string tmp = m[3];
-            tmp.erase(0, 1);
-
-            door << nick_color << parse_nick(m[0]) << door::reset << " " << tmp
-                 << door::nl;
-          }
-        }
+        render(*msg, door, irc);
       }
     } while (msg);
 
@@ -457,6 +136,8 @@ int main(int argc, char *argv[]) {
       in_door = false;
   }
 
+  // We miss the ERROR / connection closed message
+
   io_context.stop();
   Thread.join();
 

+ 98 - 0
render.cpp

@@ -0,0 +1,98 @@
+#include "render.h"
+
+void render(std::vector<std::string> irc_msg, door::Door &door,
+            ircClient &irc) {
+  // std::vector<std::string> irc_msg = *msg;
+
+  if (irc_msg.size() == 1) {
+    // system message
+    door << "(" << irc_msg[0] << ")" << door::nl;
+    return;
+  }
+
+  std::string cmd = irc_msg[1];
+
+  if (irc_msg[0] == "ERROR") {
+    std::string tmp = irc_msg[1];
+    if (tmp[0] == ':')
+      tmp.erase(0, 1);
+    door << "* ERROR: " << tmp << door::nl;
+  }
+
+  if (cmd == "366") {
+    // end of names, output and clear
+    std::string channel = split_limit(irc_msg[3], 2)[0];
+
+    irc.channels_lock.lock();
+    door << "* users on " << channel << " : ";
+    for (auto name : irc.channels[channel]) {
+      door << name << " ";
+    }
+    irc.channels_lock.unlock();
+    door << door::nl;
+    // names.clear();
+  }
+
+  if (cmd == "372") {
+    // MOTD
+    std::string temp = irc_msg[3];
+    temp.erase(0, 1);
+    door << "* " << temp << door::nl;
+  }
+
+  // 400 and 500 are errors?  should show those.
+  if ((cmd[0] == '4') or (cmd[0] == '5')) {
+    std::string tmp = irc_msg[3];
+    if (tmp[0] == ':')
+      tmp.erase(0, 1);
+
+    door << "* " << tmp << door::nl;
+  }
+
+  if (cmd == "NOTICE") {
+    std::string tmp = irc_msg[3];
+    tmp.erase(0, 1);
+
+    door << parse_nick(irc_msg[0]) << " NOTICE " << tmp << door::nl;
+  }
+
+  if (cmd == "ACTION") {
+    if (irc_msg[2][0] == '#') {
+      door << "* " << parse_nick(irc_msg[0]) << "/" << irc_msg[2] << " "
+           << irc_msg[3] << door::nl;
+    } else {
+      door << "* " << parse_nick(irc_msg[0]) << " " << irc_msg[3] << door::nl;
+    }
+  }
+
+  if (cmd == "TOPIC") {
+    std::string tmp = irc_msg[3];
+    tmp.erase(0, 1);
+
+    door << parse_nick(irc_msg[0]) << " set topic of " << irc_msg[2] << " to "
+         << tmp << door::nl;
+  }
+
+  if (cmd == "PRIVMSG") {
+    door::ANSIColor nick_color{door::COLOR::WHITE, door::COLOR::BLUE};
+
+    if (irc_msg[2][0] == '#') {
+      std::string tmp = irc_msg[3];
+      tmp.erase(0, 1);
+      door::ANSIColor channel_color{door::COLOR::WHITE, door::COLOR::BLUE};
+      if (irc_msg[2] == irc.talkto()) {
+        channel_color = door::ANSIColor{door::COLOR::YELLOW, door::COLOR::BLUE,
+                                        door::ATTR::BOLD};
+      }
+      door << nick_color << parse_nick(irc_msg[0])
+           << door::ANSIColor(door::COLOR::CYAN) << "/" << channel_color
+           << irc_msg[2] << door::reset << " " << tmp << door::nl;
+    } else {
+      std::string tmp = irc_msg[3];
+      tmp.erase(0, 1);
+
+      door << nick_color << parse_nick(irc_msg[0]) << door::reset << " " << tmp
+           << door::nl;
+    }
+  }
+}

+ 11 - 0
render.h

@@ -0,0 +1,11 @@
+#ifndef RENDER_H
+#define RENDER_H
+
+#include "door.h"
+#include "irc.h"
+#include <string>
+#include <vector>
+
+void render(std::vector<std::string> irc_msg, door::Door &door, ircClient &irc);
+
+#endif