IRCClient: Add handling for server responses and BANLIST command

This commit is contained in:
Brendan Coles 2020-04-05 10:36:35 +00:00 committed by Andreas Kling
parent 1e67efc5c1
commit a1b57216b8
Notes: sideshowbarker 2024-07-19 07:54:10 +09:00
4 changed files with 118 additions and 5 deletions

View file

@ -168,6 +168,14 @@ void IRCAppWindow::setup_actions()
m_client->handle_invite_user_action(window->channel().name(), input_box->text_value());
});
m_banlist_action = GUI::Action::create("Ban list", [this](auto&) {
auto* window = m_client->current_window();
if (!window || window->type() != IRCWindow::Type::Channel) {
return;
}
m_client->handle_banlist_action(window->channel().name());
});
m_voice_user_action = GUI::Action::create("Voice user", [this](auto&) {
auto* window = m_client->current_window();
if (!window || window->type() != IRCWindow::Type::Channel) {
@ -252,6 +260,7 @@ void IRCAppWindow::setup_menus()
auto& channel_menu = menubar->add_menu("Channel");
channel_menu.add_action(*m_change_topic_action);
channel_menu.add_action(*m_invite_user_action);
channel_menu.add_action(*m_banlist_action);
channel_menu.add_separator();
channel_menu.add_action(*m_voice_user_action);
channel_menu.add_action(*m_devoice_user_action);
@ -329,6 +338,7 @@ void IRCAppWindow::update_gui_actions()
bool is_open_channel = window && window->type() == IRCWindow::Type::Channel && window->channel().is_open();
m_change_topic_action->set_enabled(is_open_channel);
m_invite_user_action->set_enabled(is_open_channel);
m_banlist_action->set_enabled(is_open_channel);
m_voice_user_action->set_enabled(is_open_channel);
m_devoice_user_action->set_enabled(is_open_channel);
m_op_user_action->set_enabled(is_open_channel);

View file

@ -64,6 +64,7 @@ private:
RefPtr<GUI::Action> m_change_nick_action;
RefPtr<GUI::Action> m_change_topic_action;
RefPtr<GUI::Action> m_invite_user_action;
RefPtr<GUI::Action> m_banlist_action;
RefPtr<GUI::Action> m_voice_user_action;
RefPtr<GUI::Action> m_devoice_user_action;
RefPtr<GUI::Action> m_op_user_action;

View file

@ -48,6 +48,7 @@ enum IRCNumeric {
RPL_WHOISUSER = 311,
RPL_WHOISSERVER = 312,
RPL_WHOISOPERATOR = 313,
RPL_ENDOFWHO = 315,
RPL_WHOISIDLE = 317,
RPL_ENDOFWHOIS = 318,
RPL_WHOISCHANNELS = 319,
@ -55,7 +56,13 @@ enum IRCNumeric {
RPL_TOPICWHOTIME = 333,
RPL_NAMREPLY = 353,
RPL_ENDOFNAMES = 366,
RPL_ERR_UNKNOWNCOMMAND = 421,
RPL_BANLIST = 367,
RPL_ENDOFBANLIST = 368,
RPL_ENDOFWHOWAS = 369,
RPL_ENDOFMOTD = 376,
ERR_NOSUCHNICK = 401,
ERR_UNKNOWNCOMMAND = 421,
ERR_NICKNAMEINUSE = 433,
};
IRCClient::IRCClient()
@ -261,8 +268,14 @@ void IRCClient::handle(const Message& msg)
switch (numeric) {
case RPL_WHOISCHANNELS:
return handle_rpl_whoischannels(msg);
case RPL_ENDOFWHO:
return handle_rpl_endofwho(msg);
case RPL_ENDOFWHOIS:
return handle_rpl_endofwhois(msg);
case RPL_ENDOFWHOWAS:
return handle_rpl_endofwhowas(msg);
case RPL_ENDOFMOTD:
return handle_rpl_endofmotd(msg);
case RPL_WHOISOPERATOR:
return handle_rpl_whoisoperator(msg);
case RPL_WHOISSERVER:
@ -279,8 +292,16 @@ void IRCClient::handle(const Message& msg)
return handle_rpl_namreply(msg);
case RPL_ENDOFNAMES:
return handle_rpl_endofnames(msg);
case RPL_ERR_UNKNOWNCOMMAND:
return handle_rpl_unknowncommand(msg);
case RPL_BANLIST:
return handle_rpl_banlist(msg);
case RPL_ENDOFBANLIST:
return handle_rpl_endofbanlist(msg);
case ERR_NOSUCHNICK:
return handle_err_nosuchnick(msg);
case ERR_UNKNOWNCOMMAND:
return handle_err_unknowncommand(msg);
case ERR_NICKNAMEINUSE:
return handle_err_nicknameinuse(msg);
}
}
@ -328,6 +349,11 @@ void IRCClient::send_invite(const String& channel_name, const String& nick)
send(String::format("INVITE %s %s\r\n", nick.characters(), channel_name.characters()));
}
void IRCClient::send_banlist(const String& channel_name)
{
send(String::format("MODE %s +b\r\n", channel_name.characters()));
}
void IRCClient::send_voice_user(const String& channel_name, const String& nick)
{
send(String::format("MODE %s +v %s\r\n", channel_name.characters(), nick.characters()));
@ -630,6 +656,28 @@ void IRCClient::handle_rpl_namreply(const Message& msg)
void IRCClient::handle_rpl_endofnames(const Message&)
{
add_server_message("// End of NAMES");
}
void IRCClient::handle_rpl_banlist(const Message& msg)
{
if (msg.arguments.size() < 5)
return;
auto& channel = msg.arguments[1];
auto& mask = msg.arguments[2];
auto& user = msg.arguments[3];
auto& datestamp = msg.arguments[4];
add_server_message(String::format("* %s: %s on %s by %s", channel.characters(), mask.characters(), datestamp.characters(), user.characters()));
}
void IRCClient::handle_rpl_endofbanlist(const Message&)
{
add_server_message("// End of BANLIST");
}
void IRCClient::handle_rpl_endofwho(const Message&)
{
add_server_message("// End of WHO");
}
void IRCClient::handle_rpl_endofwhois(const Message&)
@ -637,6 +685,16 @@ void IRCClient::handle_rpl_endofwhois(const Message&)
add_server_message("// End of WHOIS");
}
void IRCClient::handle_rpl_endofwhowas(const Message&)
{
add_server_message("// End of WHOWAS");
}
void IRCClient::handle_rpl_endofmotd(const Message&)
{
add_server_message("// End of MOTD");
}
void IRCClient::handle_rpl_whoisoperator(const Message& msg)
{
if (msg.arguments.size() < 2)
@ -703,7 +761,16 @@ void IRCClient::handle_rpl_topicwhotime(const Message& msg)
ensure_channel(channel_name).add_message(String::format("*** (set by %s at %s)", nick.characters(), setat.characters()), Color::Blue);
}
void IRCClient::handle_rpl_unknowncommand(const Message& msg)
void IRCClient::handle_err_nosuchnick(const Message& msg)
{
if (msg.arguments.size() < 3)
return;
auto& nick = msg.arguments[1];
auto& message = msg.arguments[2];
add_server_message(String::format("* %s :%s", nick.characters(), message.characters()));
}
void IRCClient::handle_err_unknowncommand(const Message& msg)
{
if (msg.arguments.size() < 2)
return;
@ -711,6 +778,14 @@ void IRCClient::handle_rpl_unknowncommand(const Message& msg)
add_server_message(String::format("* Unknown command: %s", cmd.characters()));
}
void IRCClient::handle_err_nicknameinuse(const Message& msg)
{
if (msg.arguments.size() < 2)
return;
auto& nick = msg.arguments[1];
add_server_message(String::format("* %s :Nickname in use", nick.characters()));
}
void IRCClient::register_subwindow(IRCWindow& subwindow)
{
if (subwindow.type() == IRCWindow::Server) {
@ -787,6 +862,19 @@ void IRCClient::handle_user_command(const String& input)
}
return;
}
if (command == "/BANLIST") {
if (parts.size() >= 2) {
auto channel = parts[1];
send_banlist(channel);
} else {
auto* window = current_window();
if (!window || window->type() != IRCWindow::Type::Channel)
return;
auto channel = window->channel().name();
send_banlist(channel);
}
return;
}
if (command == "/TOPIC") {
if (parts.size() < 2)
return;
@ -895,6 +983,11 @@ void IRCClient::handle_invite_user_action(const String& channel, const String& n
send_invite(channel, nick);
}
void IRCClient::handle_banlist_action(const String& channel)
{
send_banlist(channel);
}
void IRCClient::handle_voice_user_action(const String& channel, const String& nick)
{
send_voice_user(channel, nick);

View file

@ -110,6 +110,7 @@ public:
void handle_change_nick_action(const String& nick);
void handle_change_topic_action(const String& channel_name, const String&);
void handle_invite_user_action(const String& channel_name, const String& nick);
void handle_banlist_action(const String& channel_name);
void handle_voice_user_action(const String& channel_name, const String& nick);
void handle_devoice_user_action(const String& channel_name, const String& nick);
void handle_op_user_action(const String& channel_name, const String& nick);
@ -145,6 +146,7 @@ private:
void send_notice(const String& target, const String&);
void send_topic(const String& channel_name, const String&);
void send_invite(const String& channel_name, const String& nick);
void send_banlist(const String& channel_name);
void send_voice_user(const String& channel_name, const String& nick);
void send_devoice_user(const String& channel_name, const String& nick);
void send_op_user(const String& channel_name, const String& nick);
@ -163,12 +165,19 @@ private:
void handle_rpl_whoisserver(const Message&);
void handle_rpl_whoisoperator(const Message&);
void handle_rpl_whoisidle(const Message&);
void handle_rpl_endofwho(const Message&);
void handle_rpl_endofwhois(const Message&);
void handle_rpl_endofwhowas(const Message&);
void handle_rpl_endofmotd(const Message&);
void handle_rpl_whoischannels(const Message&);
void handle_rpl_topicwhotime(const Message&);
void handle_rpl_endofnames(const Message&);
void handle_rpl_endofbanlist(const Message&);
void handle_rpl_namreply(const Message&);
void handle_rpl_unknowncommand(const Message&);
void handle_rpl_banlist(const Message&);
void handle_err_nosuchnick(const Message&);
void handle_err_unknowncommand(const Message&);
void handle_err_nicknameinuse(const Message&);
void handle_privmsg_or_notice(const Message&, PrivmsgOrNotice);
void handle_nick(const Message&);
void handle(const Message&);