فهرست منبع

Updated parser.

Steve Thielemann 3 سال پیش
والد
کامیت
65d563ff15
3فایلهای تغییر یافته به همراه103 افزوده شده و 79 حذف شده
  1. 1 1
      input.cpp
  2. 47 35
      irc.cpp
  3. 55 43
      render.cpp

+ 1 - 1
input.cpp

@@ -138,7 +138,7 @@ void parse_input(door::Door &door, ircClient &irc) {
           "PRIVMSG " + irc.talkto() + " :\x01" + "ACTION " + cmd[1] + "\x01";
       irc.write(tmp);
       // build msg for render
-      tmp = ":" + irc.nick + "!" + " ACTION " + irc.talkto() + " " + cmd[1];
+      tmp = ":" + irc.nick + "!" + " ACTION " + irc.talkto() + " :" + cmd[1];
       message_stamp msg;
       msg.buffer = irc_split(tmp);
       render(msg, door, irc);

+ 47 - 35
irc.cpp

@@ -59,9 +59,23 @@ std::vector<std::string> split_limit(std::string &text, int max) {
  * @return std::vector<std::string>
  */
 std::vector<std::string> irc_split(std::string &text) {
+  size_t msgpos = text.find(" :");
+  std::string message;
+  if (msgpos != std::string::npos) {
+    message = text.substr(msgpos + 2);
+    text.erase(msgpos);
+  }
+  std::vector<std::string> results;
+
+  /*
   if (text[0] != ':')
-    return split_limit(text, 2);
-  return split_limit(text, 4);
+    results = split_limit(text, 2);
+  results = split_limit(text, 4);
+  */
+  results = split_limit(text, -1);
+  if (!message.empty())
+    results.push_back(message);
+  return results;
 }
 
 /**
@@ -274,7 +288,7 @@ void ircClient::message(std::string msg) {
 void ircClient::receive(std::string &text) {
   message_stamp ms;
   ms.buffer = irc_split(text);
-  std::vector<std::string> &parts = ms.buffer; // irc_split(text);
+  std::vector<std::string> &parts = ms.buffer;
 
   if (logging) {
     // this also shows our parser working
@@ -299,22 +313,26 @@ void ircClient::receive(std::string &text) {
 
   if (parts.size() >= 3) {
     std::string source = parse_nick(parts[0]);
-    std::string cmd = parts[1];
-    std::string msg_to = parts[2];
+    std::string &cmd = parts[1];
+    std::string &msg_to = parts[2];
 
     std::string msg;
-    if (parts.size() == 4) {
-      msg = parts[3];
+    if (parts.size() >= 4) {
+      msg = parts[parts.size() - 1];
     }
 
-    if (cmd == "JOIN") {
-      msg_to.erase(0, 1); // channel
+    if (logging) {
+      // this also shows our parser working
+      std::ofstream &l = log();
+      l << "IRC: [SRC:" << source << "] [CMD:" << cmd << "] [TO:" << msg_to
+        << "] [MSG:" << msg << "]" << std::endl;
+    }
 
+    if (cmd == "JOIN") {
       channels_lock.lock();
       if (nick == source) {
         // yes, we are joining
-        std::string output =
-            "You have joined " + msg_to + " [talkto = " + msg_to + "]";
+        std::string output = "You have joined " + msg_to;
         message(output);
         talkto(msg_to);
         // insert empty set here.
@@ -343,11 +361,11 @@ void ircClient::receive(std::string &text) {
 
         if (!channels.empty()) {
           talkto(channels.begin()->first);
-          output += " [talkto = " + talkto() + "]";
+          // output += " [talkto = " + talkto() + "]";
         } else {
           talkto("");
         }
-        message(output);
+        // message(output);
 
       } else {
         std::string output = source + " has left " + msg_to;
@@ -363,12 +381,11 @@ void ircClient::receive(std::string &text) {
     }
 
     if (cmd == "KICK") {
-      std::string wholeft = split_limit(parts[3], 2)[0];
       std::string output =
-          source + " has kicked " + wholeft + " from " + msg_to;
+          source + " has kicked " + parts[3] + " from " + msg_to;
 
       channels_lock.lock();
-      if (wholeft == nick) {
+      if (parts[3] == nick) {
         channels.erase(msg_to);
         if (!channels.empty()) {
           talkto(channels.begin()->first);
@@ -377,7 +394,7 @@ void ircClient::receive(std::string &text) {
           talkto("");
         }
       } else {
-        channels[msg_to].erase(wholeft);
+        channels[msg_to].erase(parts[3]);
       }
 
       find_max_nick_length();
@@ -407,13 +424,7 @@ void ircClient::receive(std::string &text) {
     if (cmd == "353") {
       // NAMES list for channel
       std::vector<std::string> names_list = split_limit(msg);
-      names_list.erase(names_list.begin());
-      std::string channel = names_list.front();
-      names_list.erase(names_list.begin());
-
-      if ((names_list.size() > 0) and (names_list[0][0] == ':')) {
-        names_list[0].erase(0, 1);
-      }
+      std::string channel = parts[4];
 
       channels_lock.lock();
       if (channels.find(channel) == channels.end()) {
@@ -431,7 +442,7 @@ void ircClient::receive(std::string &text) {
     }
 
     if (cmd == "NICK") {
-      msg_to.erase(0, 1);
+      // msg_to.erase(0, 1);
 
       channels_lock.lock();
       for (auto &ch : channels) {
@@ -450,26 +461,25 @@ void ircClient::receive(std::string &text) {
     if (cmd == "PRIVMSG") {
       // Possibly a CTCP request.  Let's see
       std::string message = msg;
-      if ((message[0] == ':') and (message[1] == '\x01') and
-          (message[message.size() - 1] == '\x01')) {
+      if ((message[0] == '\x01') and (message[message.size() - 1] == '\x01')) {
         // CTCP MESSAGE FOUND  strip \x01's
-        message.erase(0, 2);
+        message.erase(0, 1);
         message.erase(message.size() - 1);
 
         std::vector<std::string> ctcp_cmd = split_limit(message, 2);
 
         if (ctcp_cmd[0] != "ACTION") {
           std::string msg =
-              "Received CTCP " + ctcp_cmd[0] + " from " + parse_nick(parts[0]);
+              "Received CTCP " + ctcp_cmd[0] + " from " + parse_nick(source);
           this->message(msg);
           if (logging) {
-            log() << "CTCP : [" << message << "] from " + parse_nick(parts[0])
+            log() << "CTCP : [" << message << "] from " + parse_nick(source)
                   << std::endl;
           }
         }
 
         if (message == "VERSION") {
-          std::string reply_to = parse_nick(parts[0]);
+          std::string reply_to = parse_nick(source);
           boost::format fmt =
               boost::format("NOTICE %1% :\x01VERSION Bugz IRC thing V0.1\x01") %
               reply_to;
@@ -481,7 +491,7 @@ void ircClient::receive(std::string &text) {
         if (message.substr(0, 5) == "PING ") {
           message.erase(0, 5);
           boost::format fmt = boost::format("NOTICE %1% :\x01PING %2%\x01") %
-                              parse_nick(parts[0]) % message;
+                              parse_nick(source) % message;
           std::string response = fmt.str();
           write(response);
           return;
@@ -494,7 +504,7 @@ void ircClient::receive(std::string &text) {
               std::put_time(std::localtime(&in_time_t), "%c"));
 
           boost::format fmt = boost::format("NOTICE %1% :\x01TIME %2%\x01") %
-                              parse_nick(parts[0]) % datetime;
+                              parse_nick(source) % datetime;
           std::string response = fmt.str();
           write(response);
           return;
@@ -504,9 +514,11 @@ void ircClient::receive(std::string &text) {
           message.erase(0, 7);
           parts[1] = "ACTION"; // change PRIVMSG to ACTION
           parts[3] = message;
+        } else {
+          // What should I do with unknown CTCP commands?
+          // Unknown CTCP command.  Eat it.
+          return;
         }
-
-        // I have this parsed this far, now what can I do with it?!
       }
     }
   }

+ 55 - 43
render.cpp

@@ -83,22 +83,28 @@ void render(message_stamp &msg_stamp, door::Door &door, ircClient &irc) {
       door::ANSIColor{door::COLOR::YELLOW, door::COLOR::BLUE, door::ATTR::BOLD};
   door::ANSIColor text_color{door::COLOR::WHITE};
 
-  std::string cmd = irc_msg[1];
-
-  if (irc_msg[0] == "ERROR") {
-    std::string tmp = irc_msg[1];
+  std::string &source = irc_msg[0];
+  std::string &cmd = irc_msg[1];
+  std::string target;
+  if (irc_msg.size() > 2)
+    target = irc_msg[2];
+  std::string msg;
+  if (irc_msg.size() > 3)
+    msg = irc_msg[irc_msg.size() - 1];
+
+  if (source == "ERROR") {
+    std::string tmp = cmd;
+    /*
     if (tmp[0] == ':')
       tmp.erase(0, 1);
+      */
     stamp(msg_stamp.stamp, door);
     door << error << "* ERROR: " << tmp << door::reset << door::nl;
   }
 
   if (cmd == "332") {
     // joined channel with topic
-    std::vector<std::string> channel_topic = split_limit(irc_msg[3], 2);
-    channel_topic[1].erase(0, 1);
-    std::string output =
-        "Topic for " + channel_topic[0] + " is: " + channel_topic[1];
+    std::string output = "Topic for " + irc_msg[3] + " is: " + msg;
     stamp(msg_stamp.stamp, door);
     int left = stamp_length;
     door << info;
@@ -108,13 +114,19 @@ void render(message_stamp &msg_stamp, door::Door &door, ircClient &irc) {
 
   if (cmd == "366") {
     // end of names, output and clear
-    std::string channel = split_limit(irc_msg[3], 2)[0];
+    std::string channel = irc_msg[3]; // split_limit(irc_msg[3], 2)[0];
 
     irc.channels_lock.lock();
     stamp(msg_stamp.stamp, door);
-    door << info << "* users on " << channel << " : ";
-    for (auto name : irc.channels[channel]) {
-      door << name << " ";
+    int count = irc.channels[channel].size();
+
+    if (count > 10) {
+      door << info << "* " << count << " users on " << channel;
+    } else {
+      door << info << "* users on " << channel << " : ";
+      for (auto name : irc.channels[channel]) {
+        door << name << " ";
+      }
     }
     irc.channels_lock.unlock();
     door << door::reset << door::nl;
@@ -123,19 +135,19 @@ void render(message_stamp &msg_stamp, door::Door &door, ircClient &irc) {
 
   if (cmd == "372") {
     // MOTD
-    std::string temp = irc_msg[3];
-    temp.erase(0, 1);
+    // std::string temp = irc_msg[3];
+    // temp.erase(0, 1);
     stamp(msg_stamp.stamp, door);
-    door << info << "* " << temp << door::reset << door::nl;
+    door << info << "* " << msg << door::reset << 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);
+    // std::string tmp = irc_msg[3];
+    // if (tmp[0] == ':')
+    //  tmp.erase(0, 1);
     stamp(msg_stamp.stamp, door);
-    door << error << "* " << tmp << door::reset << door::nl;
+    door << error << "* " << msg << door::reset << door::nl;
   }
 
   if (cmd == "NOTICE") {
@@ -152,17 +164,18 @@ void render(message_stamp &msg_stamp, door::Door &door, ircClient &irc) {
   }
 
   if (cmd == "ACTION") {
-    if (irc_msg[2][0] == '#') {
+    // if (irc_msg[2][0] == '#') {
+    if (target[0] == '#') {
       stamp(msg_stamp.stamp, door);
       int left = stamp_length;
-      if (irc_msg[2] == irc.talkto())
+      if (target == irc.talkto())
         door << active_channel_color;
       else
         door << channel_color;
-      door << irc_msg[2] << "/" << nick_color;
-      left += irc_msg[2].size() + 1;
+      door << target << "/" << nick_color;
+      left += target.size() + 1;
 
-      std::string nick = parse_nick(irc_msg[0]);
+      std::string nick = parse_nick(source);
       left += nick.size();
       int len = irc.max_nick_length - nick.size();
       if (len > 0) {
@@ -171,7 +184,7 @@ void render(message_stamp &msg_stamp, door::Door &door, ircClient &irc) {
       }
       left += 3;
       door << "* " << nick << " ";
-      word_wrap(left, door, irc_msg[3]);
+      word_wrap(left, door, msg); // irc_msg[3]);
       // << irc_msg[3] << door::reset << door::nl;
       /*
       door << "* " << irc_msg[2] << "/" << parse_nick(irc_msg[0]) << " "
@@ -180,10 +193,10 @@ void render(message_stamp &msg_stamp, door::Door &door, ircClient &irc) {
     } else {
       stamp(msg_stamp.stamp, door);
       int left = stamp_length;
-      std::string nick = parse_nick(irc_msg[0]);
+      std::string nick = parse_nick(source);
       door << nick_color << "* " << nick << " ";
       left += 3 + nick.size();
-      word_wrap(left, door, irc_msg[3]);
+      word_wrap(left, door, msg); // irc_msg[3]);
       // << irc_msg[3] << door::reset << door::nl;
 
       // door << "* " << parse_nick(irc_msg[0]) << " " << irc_msg[3] <<
@@ -205,21 +218,20 @@ void render(message_stamp &msg_stamp, door::Door &door, ircClient &irc) {
   }
 
   if (cmd == "PRIVMSG") {
-    if (irc_msg[2][0] == '#') {
-      std::string tmp = irc_msg[3];
-      tmp.erase(0, 1);
+    if (target[0] == '#') {
+      // std::string tmp = irc_msg[3];
+      // tmp.erase(0, 1);
 
       stamp(msg_stamp.stamp, door);
       int left = stamp_length;
 
-      if (irc_msg[2] == irc.talkto())
+      if (target == irc.talkto())
         door << active_channel_color;
       else
         door << channel_color;
-      door << irc_msg[2];
-      door << "/" << nick_color;
-      left += irc_msg[2].size() + 1;
-      std::string nick = parse_nick(irc_msg[0]);
+      door << target << "/" << nick_color;
+      left += target.size() + 1;
+      std::string nick = parse_nick(source);
       left += nick.size();
       int len = irc.max_nick_length + 2 - nick.size();
       if (len > 0) {
@@ -228,31 +240,31 @@ void render(message_stamp &msg_stamp, door::Door &door, ircClient &irc) {
       }
       door << nick << " " << text_color;
       left++;
-      word_wrap(left, door, tmp);
+      word_wrap(left, door, msg); // tmp);
       // << tmp << door::reset << door::nl;
       /*
       door << channel_color << irc_msg[2] << "/" << nick_color
            << parse_nick(irc_msg[0]) << door::reset << " " << tmp << door::nl;
       */
     } else {
-      std::string tmp = irc_msg[3];
-      tmp.erase(0, 1);
+      // std::string tmp = irc_msg[3];
+      // tmp.erase(0, 1);
       stamp(msg_stamp.stamp, door);
       int left = stamp_length;
       std::string nick = parse_nick(irc_msg[0]);
       door << nick_color << nick << door::reset << " ";
       left += nick.size() + 1;
-      word_wrap(left, door, tmp);
+      word_wrap(left, door, msg);
       // << tmp << door::nl;
     }
   }
 
   if (cmd == "NICK") {
-    std::string tmp = irc_msg[2];
-    tmp.erase(0, 1);
+    // std::string tmp = irc_msg[2];
+    // tmp.erase(0, 1);
     stamp(msg_stamp.stamp, door);
-    door << info << "* " << parse_nick(irc_msg[0]) << " is now known as " << tmp
-         << door::reset << door::nl;
+    door << info << "* " << parse_nick(irc_msg[0]) << " is now known as "
+         << target << door::reset << door::nl;
   }
 
   if (cmd == "MODE") {