You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.3 KiB
109 lines
2.3 KiB
#include <string> |
|
#include <vector> |
|
#include <istream> |
|
#include <sstream> |
|
#include <iostream> |
|
#include <deque> |
|
#include <optional> |
|
|
|
#include "irc.h" |
|
|
|
#include <SDL.h> // for SDL_GetTicks(); |
|
|
|
|
|
enum class ircommand parse_command(const std::string& command) { |
|
if (!command.compare("PRIVMSG")) { |
|
return ircommand::PRIVMSG; |
|
} |
|
if (!command.compare("JOIN")) { |
|
return ircommand::JOIN; |
|
} |
|
if (!command.compare("QUIT")) { |
|
return ircommand::QUIT; |
|
} |
|
if (!command.compare("PING")) { |
|
return ircommand::PING; |
|
} |
|
|
|
return ircommand::UNKNOWN; |
|
} |
|
|
|
|
|
/* |
|
https://datatracker.ietf.org/doc/html/rfc1459.html#section-2.3.1 |
|
*/ |
|
std::optional<msg> |
|
parse_chat_message(const std::string &message) |
|
{ |
|
// :nightbot!nightbot@nightbot.tmi.twitch.tv PRIVMSG #ironmouse :If you would like to support ironmouse donations are not required but greatly appreciated: https://www.streamlabs.com/ironmouse |
|
|
|
struct msg m {}; |
|
int start = 0; |
|
int end = 0; |
|
|
|
if (message[0] == ':') { |
|
// prefix |
|
|
|
// parse user from prefix |
|
start = message.find("!", start); |
|
end = message.find("@", start); |
|
if (start != std::string::npos && end != std::string::npos && start < end) { |
|
start++; |
|
m.user = message.substr(start, end - start); |
|
end = message.find(" ", end); |
|
} else { |
|
start = 1; |
|
end = message.find(" ", start); |
|
m.user = message.substr(start, end - start); |
|
} |
|
} |
|
|
|
// command |
|
start = message.find_first_not_of(" ", end); |
|
end = message.find(" ", start); |
|
if (start == std::string::npos || end == std::string::npos) { |
|
return {}; |
|
} |
|
auto command = message.substr(start, end - start); |
|
m.cmd = parse_command(command); |
|
|
|
if (m.cmd == ircommand::PRIVMSG) { |
|
// channel |
|
start = message.find("#"); |
|
end = message.find(" ", start); |
|
start++; |
|
m.channel = message.substr(start, end - start); |
|
} |
|
|
|
start = message.find(":", end); // end of command params |
|
start++; |
|
|
|
|
|
// message |
|
m.message = message.substr(start, message.size() - start); |
|
m.complete_message = message; |
|
|
|
return m; |
|
} |
|
|
|
|
|
void parse_chat_messages(const std::string& messages, |
|
std::deque<msg> &message_queue) { |
|
// parse some input from server |
|
|
|
int start = 0; |
|
|
|
std::vector<std::string> tokens{}; |
|
std::istringstream iss(messages); |
|
std::string s; |
|
while (std::getline(iss, s)) { |
|
auto msg = parse_chat_message(s); |
|
msg->received_at = SDL_GetTicks(); |
|
if (msg) { |
|
message_queue.push_back(*msg); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|