Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/ircserv",
"args": ["1234", "1234"], //<port> <password> CHANGE PORT IN BIND FAILURE
"args": ["1235", "1234"], //<port> <password> CHANGE PORT IN BIND FAILURE
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
Expand Down
11 changes: 7 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"files.associations": {
"stdexcept": "cpp",
"iosfwd": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
Expand All @@ -10,6 +8,7 @@
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"array": "cpp",
Expand All @@ -21,6 +20,7 @@
"cstdint": "cpp",
"deque": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
Expand All @@ -38,7 +38,10 @@
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
Expand All @@ -48,8 +51,8 @@
"ranges": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"typeinfo": "cpp",
"set": "cpp"
"typeinfo": "cpp"
}
}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ NAME = ircserv
DEBUG ?= 0

CC = c++
CXXFLAGS = -std=c++98 -g
CXXFLAGS = -std=c++98 -g3 #-Wall -Werror -Wextra

ifeq ($(DEBUG),1)
CPPFLAGS += -DDEBUG
Expand Down
28 changes: 1 addition & 27 deletions Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,6 @@ int Server::new_connection()
_users.push_back(new_user);
new_user->set_fd(connection_socket);

//might need to be somewhere else
// Server::register_client(new_user);

// new_user->set_auth(true); --now in PASS
// ^^ might have to use this here instead of register_client as we are now registering in USER and NICK

struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET;
ev.data.ptr = new_user;
Expand All @@ -143,8 +137,7 @@ int Server::client_message(User *user)
if (bytes == -1)
{
std::cout << RED << "~Server~ recv() failure [456]\n" << RST;
// perror("recv");
throw std::runtime_error("Error in recv()");
throw std::runtime_error("Error in recv()"); //TODO -leaks?
return (1);
}

Expand All @@ -157,13 +150,11 @@ int Server::client_message(User *user)
}

LOG("Received raw message from FD: " << user->get_fd() << ": " << std::string(buf, bytes));
// std::cout << "\tbuf: " << buf;
_msg.append(buf);

// processing each commang in _msg
std::stringstream ss(_msg);
std::string line;
// LOG("Processing command: " + line + " from user " + user->get_user());

while(std::getline(ss, line, '\n'))
{
Expand Down Expand Up @@ -197,34 +188,18 @@ int Server::get_command(User *user, std::string msg)
std::stringstream params;
params << ss.rdbuf(); // Get the remaining parameters
LOG("Calling command function for: " + word + " params: " + params.str());
// std::cout << "Calling command function for: " << word << " with params: " << RED << params.str() << std::endl << RST;
// clearing after processing the command
// if (ret == 0)
// _msg.clear();
return (this->*(it->second))(user, params);
}
else
{
reply(user, "", "421", word, ":Unknown command"); // ERR_UNKNOWNCOMMAND
// clearing invalids also --can't do this because command might be valid, but not complete (nc ctrl-d from subject)
// _msg.clear();
return 1;
}
}

void Server::reply(User *user, std::string prefix, std::string command,
std::string target, std::string message)
{
// std::string reply;
// if (!prefix.empty())
// reply += ":" + prefix + " ";
// reply += command;
// if (!target.empty())
// reply += " " + target;
// if (!message.empty())
// reply += " :" + message;
// reply += "\n"; // correct line ending ?

std::string reply;
if (!prefix.empty())
reply.append(prefix + " ");
Expand Down Expand Up @@ -263,7 +238,6 @@ User *Server::get_user_from_nick(std::string nick)
void Server::add_user(User *user)
{
_users.push_back(user);
// register_client(user);
}

void Server::remove_user(User *user)
Expand Down
107 changes: 23 additions & 84 deletions ServerCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
can be ignored - https://ircv3.net/specs/extensions/capability-negotiation.html */
int Server::CAP(User *user, std::stringstream &command)
{
// std::string buf;
// command >> buf;
(void)user;
(void)command;
return (0);
Expand Down Expand Up @@ -61,7 +59,6 @@ int Server::NICK(User *user, std::stringstream &command)
{
register_client(user);
}
// std::cout << "nick successful: " << user->get_nick() << "\n";
return (0);
}

Expand Down Expand Up @@ -116,7 +113,6 @@ int Server::PASS(User *user, std::stringstream &command)
user->set_auth(true);
else
Server::reply(user, "", "", user->get_nick(), "User already authenticated."); //not standard irc error -- might need to be removed/changed to std error
// std::cout << "PASS successful, auth: " << user->get_auth() << "\n";
return (0);
}
int Server::QUIT(User *user, std::stringstream &command)
Expand Down Expand Up @@ -250,10 +246,7 @@ int Server::KICK(User *user, std::stringstream &command)
for (std::set<User *>::iterator it = channel->get_members().begin(); it != channel->get_members().end(); ++it)
{
reply((*it), user->get_prefix(), "KICK " + channel_name, target_nick, kick_reason); //might be server prefix
// send((*it)->get_fd(), kick_msg.c_str(), kick_msg.length(), 0);
}

std::cout << "User " << target->get_nick() << " was kicked from channel " << channel_name << "\n";
return (0);
}

Expand Down Expand Up @@ -326,31 +319,11 @@ int Server::INVITE(User *user, std::stringstream &command)
reply(user, "", "341", channel_name, target->get_nick() + " :Invited");

// notify the invitee (is this even a word lol)
std::string invite_msg = ":" + user->get_prefix() + " INVITE " + target_nick + " :" + channel_name + "\n";
// send(target->get_fd(), invite_msg.c_str(), invite_msg.length(), 0);
reply(target, user->get_prefix(), "", "INVITE " + target->get_nick(), channel->get_name());
std::cout << "User " << target->get_nick() << " has been invited to the " << channel_name << "\n";
return (0);
}

/* //ACCEPT <invited_server>
int Server::ACCEPT(User *user, std::stringstream &command)
{
int ret = 0;
std::string channel_name;
command >> channel_name;

Channel *channel = get_channel(channel_name);
if (channel && channel->is_invited(user))
{
std::stringstream ss(channel->get_name());
ret = JOIN(user, ss);
}
else
return 1;
return (ret);
} */

// https://dd.ircdocs.horse/refs/commands/topic
int Server::TOPIC(User *user, std::stringstream &command)
{
Expand Down Expand Up @@ -411,11 +384,8 @@ int Server::TOPIC(User *user, std::stringstream &command)
std::string notify = ":" + user->get_nick() + "TOPIC" + channel_name + " " + topic + "\n";
for (std::set<User *>::iterator it = channel->get_members().begin(); it != channel->get_members().end(); ++it)
reply((*it), user->get_prefix(), "TOPIC", channel->get_name(), topic);
// send((*it)->get_fd(), notify.c_str(), notify.length(), 0);
}

//:dan!d@localhost TOPIC #v3 :topic
// reply(user, user->get_prefix(), "TOPIC", channel->get_name(), ":" + topic);
std::cout << "Topic in channel " << channel->get_name() << " changed to " << channel->get_topic() << "\n";
return (0);
}
Expand Down Expand Up @@ -495,13 +465,10 @@ int Server::MODE(User *user, std::stringstream &command)
}

// notify users
// std::string notify = ":" + user->get_nick() + "MODE" + target + " " + modes + "\n";
for (std::set<User *>::iterator it = channel->get_members().begin(); it != channel->get_members().end(); ++it)
reply((*it), user->get_prefix(), "MODE", target, modes);
// send((*it)->get_fd(), notify.c_str(), notify.length(), 0);
}
// handle unknown flags here?

return (0);
}

Expand All @@ -523,17 +490,23 @@ int Server::WHO(User *user, std::stringstream &command)
target_user = get_user_from_nick(mask);
if (!target_user && target_channel)
{
std::string members;
for (std::set<User *>::iterator it = target_channel->get_members().begin(); it != target_channel->get_members().end(); ++it)
reply(user, "", "352", " ", target_channel->get_name() + " " + (*it)->get_prefix()); //RPL_WHOREPLY (352)
//i don't think this is the right format, functioning right, but irssi isn't displaying
{
//check if member is op : they get '@' symbol
if (target_channel->is_operator(*it))
members += "@" + (*it)->get_nick() + " ";
else
members += (*it)->get_nick() + " ";
}
reply(user, "", "353", user->get_nick() + " = " + target_channel->get_name() , members); //RPL_NAMESREPLY (353)
}
if (!target_channel && target_user)
{
reply(user, "", "352", target_user->get_prefix(), target_user->get_realname()); //RPL_WHOREPLY (352)
//i don't think this is the right format, functioning right, but irssi isn't displaying
}

reply(user, "", "315", "ft_irc", "End of WHO list");//RPL_ENDOFWHO (315)
reply(user, "", "315", "ft_irc", "End of NAMES list");//RPL_ENDOFNAMES (366)
return (0);
}

Expand Down Expand Up @@ -561,23 +534,7 @@ int Server::LIST(User *user, std::stringstream &command)
// if no specific channel requested, listing all channels
for (std::map<std::string, Channel *>::iterator it = _channels.begin(); it != _channels.end(); ++it) {
Channel *channel = it->second;
std::stringstream ss;

// here i construct the message
// std::string reply = ":localhost 322 " + user->get_nick() + " " + channel->get_name() + " ";

// ss << channel->get_members().size();
// reply += ss.str() + " :";

// if (!channel->get_topic().empty())
// reply += channel->get_topic();
// else
// reply += "No topic";

// reply += "\n";
// Send the RPL_LIST message (RPL means reply code btw)
reply(user, "", "322", channel->get_name(), channel->get_topic());
// send(user->get_fd(), reply.c_str(), reply.length(), 0);
}
} else
{
Expand All @@ -595,36 +552,17 @@ int Server::LIST(User *user, std::stringstream &command)
// simply delete the if statement
if (single_channel[0] != '#')
single_channel = "#" + single_channel;
// Format the RPL_LIST reply
// std::string reply = ":localhost 322 " + user->get_nick() + " " + channel->get_name() + " ";
// ss << channel->get_members().size();
// reply += ss.str() + " :";


// if (!channel->get_topic().empty())
// reply += channel->get_topic();
// else
// reply += "No topic";

// reply += "\n";

// Send the RPL_LIST message
// send(user->get_fd(), reply.c_str(), reply.length(), 0);
reply(user, "", "322", channel->get_name(), channel->get_topic());
} else
{
// if Channel not found
std::string error = ":localhost 403 " + user->get_nick() + " " + single_channel + " :No such channel\n";
reply(user, "", "403", single_channel, "No such channel");
// send(user->get_fd(), error.c_str(), error.length(), 0);
}
}
}

// End the list with RPL_LISTEND
std::string list_end = ":localhost 323 " + user->get_nick() + " :End of /LIST\n";
reply(user, "", "323", "", "End of LIST");
// send(user->get_fd(), list_end.c_str(), list_end.length(), 0);
return (0);
}

Expand Down Expand Up @@ -682,13 +620,9 @@ int Server::PRIVMSG(User *user, std::stringstream &command)
return 1;
}

// constructing the message
std::string privmsg = ":" + user->get_nick() + " PRIVMSG " + target + " :" + message + "\n";

// sending it
if (!target_channel)
reply(target_user, user->get_prefix(), "PRIVMSG", target, message);
// send(target_user->get_fd(), privmsg.c_str(), privmsg.length(), 0);
else //sending to each member in the channel
{
if (target_channel->is_member(user))
Expand All @@ -697,11 +631,9 @@ int Server::PRIVMSG(User *user, std::stringstream &command)
{
if (*it != user) //send to everyone but yourself
reply((*it), user->get_prefix(), "PRIVMSG", target_channel->get_name(), message);
// send((*it)->get_fd(), privmsg.c_str(), privmsg.length(), 0);
}
}
}
// std::cout << "PRIVMSG successful\n";
return (0);
}

Expand Down Expand Up @@ -838,7 +770,6 @@ int Server::PART(User *user, std::stringstream &command)
return 1;
}


//get reason for parting
getline(command, reason);

Expand All @@ -852,19 +783,27 @@ int Server::PART(User *user, std::stringstream &command)
std::string part_msg = ":" + user->get_nick() + " PART " + name + reason +"\n";
for (std::set<User *>::iterator it = channel->get_members().begin(); it != channel->get_members().end(); ++it)
if ((*it) != user)
//:d!d@localhost PART #irctest :reason
reply((*it), user->get_prefix(), "PART", channel->get_name(), reason);
// send((*it)->get_fd(), part_msg.c_str(), part_msg.length(), 0);
//:d!d@localhost PART #irctest :reason
// reply(user, user->get_prefix(), "PART", channel->get_name(), reason);

std::cout << "user " << user->get_nick() << " removed from channel " << channel->get_name() << "\n";
// LOG("Prefix: " << user->get_prefix());
// LOG("User " << user->get_nick() << " removed from channel " << channel->get_name());

channel->remove_member(user);
user->leave_channel(channel);

// remove empty channel
if (channel->get_members().empty())
remove_channel(name);
//if no operators, make the first joined member op
if (channel->get_operators().empty())
{
std::set<User *>::iterator new_op = channel->get_members().begin();
if (new_op != channel->get_members().end())
{
channel->add_operator((*new_op));
LOG((*new_op)->get_prefix() + " has been made op on " + channel->get_name());
}
}
return (0);
}

Expand Down
Loading