commit d426297b2aed5843387c818fe81a8bcf0f889adf Author: Danny Jonker Date: Sat Aug 3 21:04:44 2024 +0200 bla diff --git a/Cap.cpp b/Cap.cpp new file mode 100644 index 0000000..be9cf2a --- /dev/null +++ b/Cap.cpp @@ -0,0 +1,67 @@ +#include "Cap.hpp" +#include "../IRC.hpp" +#include + +bool Cap::validate(const User &user, const std::string &msg) +{ + std::istringstream iss(msg); + std::string word; + iss >> word; // should be CAP + iss >> word; // should be the mode + if (word == "LS") + { + this->mode = 1; // In this mode run will print the capabilities of the server + iss >> word; // Should be a code + this->code = word; // Not sure if we need it but if we do we have it. + return (true); + } + if (word == "REQ") + { + this->mode = 2; // in this mode run will acknowledge the capabilities sent by the client + size_t pos; + size_t leng; + iss >> word; // Should be a all the capabilities with a : in front of them + leng = word.length(); + pos = word.find(":") + 1; + this->capabilities = word.substr(pos, leng - pos); // remove the : + return (true); + } + std::cout << "Command without mode match" << word << std::endl; + return (false); +} + +int Cap::run(User &user, IRC::t_send_f &send) +{ + if (this->mode == 1) // Mode is LS + { + send(this->targetUser, IRCManager::getHostName + " CAP * LS :" + IRCManager::getCapabilities(); + return (0); + } + if (this->mode == 2) // mode is REQ + { + std::istringstream serverCap(IRCManager::getCapabilities); + std::istringstream clientCap; + std::string server; + std::string client; + std::string matches; + serverCap >> server; + while server[0]) + { + clientCap(this->capabilities); + clientCap >> client + while (client[0]) + { + if (client == server) + { + matches = matches + client + " "; + break; + } + clientCap >> client + } + serverCap >> server; + } + send(this->targetUser, IRCManager::getHostName + " CAP " + user.getNickName() + " ACK :" + matches; + return (0); + } + return (0); +} diff --git a/Cap.hpp b/Cap.hpp new file mode 100644 index 0000000..dfc78ea --- /dev/null +++ b/Cap.hpp @@ -0,0 +1,22 @@ +#ifndef CAP_HPP +#define CAP_HPP + +#include "../ICommand.hpp" +#include + +class Cap : public ICommand +{ + private: + int mode; + std::string lsCode; + User *targetUser; + Channel *targetChannel; + std::string *capabilities; + public: + Cap(); + ~Cap(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif diff --git a/Invite.cpp b/Invite.cpp new file mode 100644 index 0000000..ea9c711 --- /dev/null +++ b/Invite.cpp @@ -0,0 +1,33 @@ +#include "Invite.hpp" +#include "../IRC.hpp" +#include + +bool Invite::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + + std::istringstream iss(msg); + std::string word; + iss >> word; // should be INVITE + iss >> word; // should be the user you want to invite + this->targetUser = IRCManager::getUserByName(word); + iss >> word; // should be the channel you want to invite to + this->targetChannel = IRCManager::getChannelByName(word); + if (this->targetChannel) // Check if the channel exists + { + if (this->targetUser) // Check if the user exists + { + return (true); + } + return (false); + } + return (true); +} + +int Invite::run(User &user, IRC::t_send_f &send) +{ + this->targetChannel->inviteUser(this->targetUser); + send(this->targetUser, user.getNickName() + "!~" + user.getUserName() + "@" + user.getHostName() + " INVITE " + this->targetUser->getNickName() + " :" + this->targetChannel->getChannelName()); + return (0); +} diff --git a/Invite.hpp b/Invite.hpp new file mode 100644 index 0000000..620085b --- /dev/null +++ b/Invite.hpp @@ -0,0 +1,19 @@ +#ifndef INVITE_HPP +#define INVITE_HPP + +#include "../ICommand.hpp" +#include + +class Invite : public ICommand +{ + private: + User *targetUser; + Channel *targetChannel; + public: + Invite(); + ~Invite(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif diff --git a/Join.cpp b/Join.cpp new file mode 100644 index 0000000..9757f3f --- /dev/null +++ b/Join.cpp @@ -0,0 +1,52 @@ +#include "Join.hpp" +#include "../IRC.hpp" +#include + +bool Join::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + + leng = msg.length(); + pos = msg.find(" "); + name = msg.substr(pos + 1, leng - pos); + this->channel = IRCManager::getChannel(name); + if (this->channel) // Check if the channel exists + { + if (this->channel->getInviteStatus()) // If it exists do we need an invite? + { + if (this->channel->checkUserInvite(user)) // Does the user have the invite to join this chat? + { + return (true); + } + return (false); + } + } + else // The Channel doesn't exist yet + return (true); +} + +int Join::run(User &user, IRC::t_send_f &send) +{ + if (!this->channel) // Check if the channel exists + { + IRCManager::addChannel(name); // create the channel + this->channel = IRCManager::getChannel(name); + this->channel->AddUser(user); + IRCManager::makeOper(user, this->channel); + } + else // Channel exists + { + this->channel->AddUser(user); + } + std::istringstream iss(this->channel->getUserList()); + std::string target; + iss >> target; + while (target[0]) + { + send(IRCManager::getUserFromName(target), user.getNickName() + "!~" + user.getUserName() + "@" + user.getHostName() + " JOIN " + this->targetChannel->getChannelName() + " * :" + user->getRealName()); + iss >> target; + } + std::cout << user.getUserName() + " Joined " + this->channel->getChannelName(); + return (0); +} diff --git a/Join.hpp b/Join.hpp new file mode 100644 index 0000000..05f7d8a --- /dev/null +++ b/Join.hpp @@ -0,0 +1,20 @@ +#ifndef JOIN_HPP +#define JOIN_HPP + +#include "../ICommand.hpp" +#include + +class Join : public ICommand +{ + private: + Channel *channel; + std::string name; + public: + Join(); + ~Join(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif + diff --git a/Kick.cpp b/Kick.cpp new file mode 100644 index 0000000..f10f312 --- /dev/null +++ b/Kick.cpp @@ -0,0 +1,45 @@ +#include "Kick.hpp" +#include "../IRC.hpp" +#include + +bool Kick::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + + leng = msg.length(); + pos = msg.find(":"); + this->reason = msg.substr(pos, leng - pos); + if (!this->reason[0]) + this->reason = " :" + this->targetUser->getNickName(); + std::istringstream iss(msg); + std::string word; + iss >> word; // should be KICK + iss >> word; // should be the channel you want to kick from + this->targetChannel = IRCManager::getChannelByName(word); + iss >> word; // should be the user you want to kick + this->targetUser = IRCManager::getUserByName(word); + if (this->targetChannel) // Check if the channel exists + { + if (this->targetUser) // Check if the user exists + { + if (this->targetChannel->checkOper(user)) // Check if we have operator permissions in the channel + return (true); + } + } + return (false); +} + +int Kick::run(User &user, IRC::t_send_f &send) +{ + std::istringstream iss(this->targetChannel->getUserList()); + std::string target; + iss >> target; + while (target[0]) + { + send(this->targetUser, user.getNickName() + "!~" + user.getUserName() + "@" + user.getHostName() + " KICK " + this->targetChannel->getChannelName() + " " + this->targetUser->getNickName() + " :" + this->reason); + iss >> target; + } + this->targetChannel->removeUser(this->targetUser); + return (0); +} diff --git a/Kick.hpp b/Kick.hpp new file mode 100644 index 0000000..2a1d42c --- /dev/null +++ b/Kick.hpp @@ -0,0 +1,20 @@ +#ifndef KICK_HPP +#define KICK_HPP + +#include "../ICommand.hpp" +#include + +class Kick : public ICommand +{ + private: + User *targetUser; + Channel *targetChannel; + std::string reason; + public: + Kick(); + ~Kick(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif diff --git a/Mode.cpp b/Mode.cpp new file mode 100644 index 0000000..56e49f8 --- /dev/null +++ b/Mode.cpp @@ -0,0 +1,73 @@ +#include "Mode.hpp" +#include "../IRC.hpp" +#include + +bool Mode::validate(const User &user, const std::string &msg) +{ + std::istringstream iss(msg); + std::string word; + std::string permissions; + iss >> word; // should be MODE + iss >> word; // should be the channel you want to adjust permissions to + this->targetChannel = IRCManager::getChannelByName(word); + iss >> word; // should be the permissions to adjust + permissions = word; + iss >> word; // should be the user that gets affected + this->targetUser = IRCManager::getUserByName(word); + if (this->targetChannel) // Check if the channel exists + { + if (this->targetUser) // Check if the user exists + { + if (this->targetChannel->checkOper(user)) // Check if we have operator permissions in the channel + { + if (permissions.find("+") != permissions.npos()) // we are going to give a mode + { + if (permissions.find("v") != permissions.npos()) // we are going to give voice + this->voice = 1; + else if (permissions.find("b") != permissions.npos()) // we are going to give ban + this->ban = 1; + else if (permissions.find("o") != permissions.npos()) // we are going to give oper + this->oper = 1; + } + else if (permissions.find("-") != permissions.npos()) // we are going to take a mode + { + if (permissions.find("v") != permissions.npos()) // we are going to take voice + this->voice = 2; + else if (permissions.find("b") != permissions.npos()) // we are going to take ban + this->ban = 2; + else if (permissions.find("o") != permissions.npos()) // we are going to take oper + this->oper = 2; + } + if (this->voice || this->ban || this->oper) // if we need to change anything + return (true); + } + } + } + return (false); +} + +int Mode::run(User &user, IRC::t_send_f &send) +{ + if (this->voice) + { + if (this->voice == 1) + this->targetChannel->giveVoice(this->targetUser); + if (this->voice == 2) + this->targetChannel->takeVoice(this->targetUser); + } + if (this->ban) + { + if (this->ban == 1) + this->targetChannel->giveBan(this->targetUser); + if (this->ban == 2) + this->targetChannel->takeBan(this->targetUser); + } + if (this->oper) + { + if (this->oper == 1) + this->targetChannel->giveOper(this->targetUser); + if (this->oper == 2) + this->targetChannel->takeOper(this->targetUser); + } + return (0); +} diff --git a/Mode.hpp b/Mode.hpp new file mode 100644 index 0000000..aa884a8 --- /dev/null +++ b/Mode.hpp @@ -0,0 +1,23 @@ +#ifndef MODE_HPP +#define MODE_HPP + +#include "../ICommand.hpp" +#include + +class Mode : public ICommand +{ + private: + User *targetUser; + Channel *targetChannel; + int voice; + int oper; + int ban; + + public: + Mode(); + ~Mode(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif diff --git a/Nick.cpp b/Nick.cpp new file mode 100644 index 0000000..a89e518 --- /dev/null +++ b/Nick.cpp @@ -0,0 +1,65 @@ +#include "Nick.hpp" +#include "../IRC.hpp" +#include + +Nick::Nick() {} + +Nick::~Nick() {} + +bool Nick::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + + leng = msg.length(); + pos = msg.find(" "); + this->nickName = msg.substr(pos + 1, leng - pos); + // probably need to check for length and illegal characters + return true; +} + +bool Nick::validate(const Connection &conn, const std::string &msg) +{ + size_t pos; + size_t leng; + + leng = msg.length(); + pos = msg.find(" "); + this->nickName = msg.substr(pos, leng - pos); + // probably need to check for length and illegal characters + return true; +} + +int Nick::run(User &user, IRC::t_send_f &send) +{ + user->setNickName(this->nickName); + std::istringstream issc(user->getChannelList()); + std::string targetchannel; + issc >> targetchannel; + while (targetchannel[0]) + { + std::istringstream issu(IRCManager::getChannelFromName(targetchannel)->getUserList()); + std::string targetuser; + iss >> targetuser; + while (targetuser[0]) + { + send(IRCManager::getUserFromName(targetuser), user.getNickName() + "!~" + user.getUserName() + "@" + user.getHostName() + " NICK " + " :" + user->getNickName()); + issu >> targetuser; + } + issc >> targetchannel; + } + return (0); +} + +int Nick::run(Connection &conn, IRC::t_send_f &send) // second run function with Connection argument is for when user is not created yet +{ + if (conn->getNickName()) // User was called before and we will create the user here + { + IRCManager::addUser(conn, conn->getUserName(), conn->getRealName(), this->nickName()); + } + else // Nick was called before User and User will be created in User + { + conn->setNickName(this->nickName); + } + return (0); +} diff --git a/Nick.hpp b/Nick.hpp new file mode 100644 index 0000000..34b7f3a --- /dev/null +++ b/Nick.hpp @@ -0,0 +1,22 @@ +#ifndef NICK_HPP +#define NICK_HPP + +#include "../ICommand.hpp" +#include "../IRC.hpp" +#include + +class Nick : public ICommand +{ + private: + std::string nickName; + public: + Nick(); + ~Nick(); + bool validate(const User &user, const std::string &msg); + bool validate(const Connection &conn, const std::string &message); + int run(User &user, IRC::t_send_f &send); + int run(Connection &conn, IRC::t_send_f &send); +}; + +#endif + diff --git a/Part.cpp b/Part.cpp new file mode 100644 index 0000000..a0d7ae3 --- /dev/null +++ b/Part.cpp @@ -0,0 +1,61 @@ +#include "Part.hpp" +#include "../IRC.hpp" +#include +#include + +Part::Part() {} + +Part::~Part() {} + +bool Part::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + std::istringstream iss(msg); + std::string iter; + + iss >> iter; //iter will be PART, which we already know + iss >> iter; //iter will be The channel that the user is leaving + if (iter[0] == '#') // If the string starts with a # it is a channel + { + this->targetChannel = IRCManager::getChannelByName(iter); // identify channel + if (!this->targetChannel) + { + std::cout << "Channel " + iter + " Does not exist, maybe we should send something back?"; // Not sure what is the proper response here, for now we print + return false; // return false to Dmitry + } + else // The channel exists + { + if (!IRCManager::checkChannelMember(user, iter)) // check if the user is part of the channel + { + std::cout << user.getUserName() + " is not a member of " + iter + " So we would be leaving nothing"; + return false; + } + } + } + else + { + std::cout << "You can't part with a user, you can only part with channels" << std::endl; + return (false); + } + + leng = msg.length(); // get the length of the message + pos = msg.find(":") + 1; // get position of the reason + this->reason = msg.substr(pos, leng - pos); // store the reason + return true; +} + +int Part::run(User &user, IRC::t_send_f &send) +{ + std::istringstream iss(targetChannel->getUserList()); + std::string target; + + iss >> target; + while (target[0]) + { + send(IRCManager::getUserFromName(target), user.getNickName() + user.getHostName() + " PART " + this->targetChannel->getChannelName() + " " + this->reason); + iss >> target; + } + this->targetChannel->removeUser(user); + return (0); +} diff --git a/Part.hpp b/Part.hpp new file mode 100644 index 0000000..f5a5915 --- /dev/null +++ b/Part.hpp @@ -0,0 +1,20 @@ +#ifndef PART_HPP +#define PART_HPP + +#include "../ICommand.hpp" +#include + + +class Part : public ICommand +{ + private: + std::string reason; + Channel *targetChannel; + public: + Part(); + ~Part(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif diff --git a/Ping.cpp b/Ping.cpp new file mode 100644 index 0000000..1ab31f2 --- /dev/null +++ b/Ping.cpp @@ -0,0 +1,26 @@ +#include "Ping.hpp" +#include "../IRC.hpp" +#include + + +Ping::Ping() : pingID("") {} + +Ping::~Ping() {} + +bool Ping::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + + leng = msg.length(); // get the length of the message + pos = msg.find(" ") + 1; // get position of start of PingID + this->pingID = msg.substr(pos, leng - pos); // set PingID + return true; +} + +int Ping::run(User &user, IRC::t_send_f &send) +{ + send(user, "PONG " + this->pingID); + std::cout << "PONG " + this->pingID << " Sent to " << user.getUserName() << std::endl; + return (0); +} diff --git a/Ping.hpp b/Ping.hpp new file mode 100644 index 0000000..70c2f84 --- /dev/null +++ b/Ping.hpp @@ -0,0 +1,20 @@ +#ifndef PING_HPP +#define PING_HPP + +#include "../ICommand.hpp" +#include "../IRC.hpp" +#include + +class Ping : public ICommand +{ + private: + std::string pingID; + public: + Ping(); + ~Ping(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif + diff --git a/Privmsg.cpp b/Privmsg.cpp new file mode 100644 index 0000000..c92895a --- /dev/null +++ b/Privmsg.cpp @@ -0,0 +1,64 @@ +#include "Privmsg.hpp" +#include "../IRC.hpp" +#include +#include + +Privmsg::Privmsg() {} + +Privmsg::~Privmsg() {} + +bool Privmsg::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + + std::istringstream iss(message); + std::string iter; + iss >> iter; + + if (iter[0] == '#') // If the string starts with a # it is a channel + { + this->targetChannel = IRCManager::getChannelByName(iter); // identify channel + if (!this->targetChannel) + { + std::cout << "Channel " + iter + " Does not exist, maybe we should send something back?"; // Not sure what is the proper response here, for now we print + return false; // return false to Dmitry + } + else // The channel exists + { + if (!IRCManager::checkChannelMember(user, iter)) // check if the user is part of the channel + { + std::cout << user.getUserName() + " is not a member of " + iter; + return false; + } + } + } + else // else it is a user + { + this->targetUser = IRCManager::getUserByName(iter); // identify user + if (!this->targetUser) + { + std::cout << "User " + iter + " Does not exist, maybe we should send something back?"; // Not sure what is the proper response here, for now we print + return false; // return false to Dmitry + } + } + while (iter[0]) // put the rest of the string in the message + { + iss >> iter; + message = message + " " + iter; + } + return true; +} + +int Privmsg::run(User &user, IRC::t_send_f &send) +{ + if (this->targetUser) + { + send(user, user.getNickName() + user.getHostName() + " PRIVMSG " + this->targetUser->getUserName() + " " + this->message); + std::cout << user.getUserName() + " sent a message to " + this->targetUser.getUserName(); + } + else + send(user, user.getNickName() + user.getHostName() + " PRIVMSG " + this->targetChannel->getChannelName() + " " + this->message); + std::cout << user.getUserName() + " sent a message to " + this->targetChannel.getChannelName(); + return (0); +} diff --git a/Privmsg.hpp b/Privmsg.hpp new file mode 100644 index 0000000..ea927a0 --- /dev/null +++ b/Privmsg.hpp @@ -0,0 +1,22 @@ +#ifndef PRIVMSG_HPP +#define PRIVMSG_HPP + +#include "../ICommand.hpp" +#include "../User.hpp" +#include + + +class Privmsg : public ICommand +{ + private: + User *targetUser; + Channel *targetChannel; + std::string message; + public: + Privmsg(); + ~Privmsg(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif diff --git a/Quit.cpp b/Quit.cpp new file mode 100644 index 0000000..bc9986b --- /dev/null +++ b/Quit.cpp @@ -0,0 +1,39 @@ +#include "Quit.hpp" +#include "../IRC.hpp" +#include +#include + + +Quit::Quit() {} + +Quit::~Quit() {} + +bool Quit::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + + leng = msg.length(); + pos = msg.find(" "); + this->reason = msg.substr(pos, leng - pos); + return true; +} + +int Quit::run(User &user, IRC::t_send_f &send) +{ + std::istringstream iss(user->getChannelList()); + std::string target; + + iss >> target; + while (target[0]) + { + send(IRCManager::getChannelFromName(target), user.getNickName() + user.getHostName() + " Quit " + this->reason); + iss >> target; + if (!user->getRegistered()) + IRCManager::removeUserFromChannel(user, IRCManager::getChannelFromName(target)); + } + if (!user->getRegistered()) + { + IRCManager::delUser(user); + } +} diff --git a/Quit.hpp b/Quit.hpp new file mode 100644 index 0000000..b07bbb3 --- /dev/null +++ b/Quit.hpp @@ -0,0 +1,20 @@ +#ifndef QUIT_HPP +#define QUIT_HPP + +#include "../ICommand.hpp" +#include + + +class Quit : public ICommand +{ + private: + std::string reason; + public: + Quit(); + ~Quit(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif + diff --git a/Topic.cpp b/Topic.cpp new file mode 100644 index 0000000..c30dd8f --- /dev/null +++ b/Topic.cpp @@ -0,0 +1,45 @@ +#include "Topic.hpp" +#include "../IRC.hpp" +#include + +bool Topic::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + + leng = msg.length(); + pos = msg.find(":") + 1; + std::istringstream iss(msg); + std::string word; + + this->topic = msg.substr(pos, leng - pos); + iss >> word; // should be TOPIC + iss >> word; // should be the Channel you want to change + this->targetChannel = IRCManager::getChannelByName(word); + if (this->targetChannel) // Check if the channel exists + { + if (this->targetChannel->getUserChangeTopic()) // Check if a user has permission to change the topic + return (true); + if (this->targetChannel->checkOperator(user)) // Check if we have operator permissions in the channel + return (true); + } + return (false); +} + +int Topic::run(User &user, IRC::t_send_f &send) +{ + this->targetChannel->setTopic(this->topic); + std::istringstream iss(this->targetChannel->getUserList()); + std::string target; + iss >> target; + while (target[0]) + { + send(IRCManager::getUserFromName(target), user.getNickName() + "!~" + user.getUserName() + "@" + user.getHostName() + " TOPIC " + this->targetChannel->getChannelName() + " * :" + this->topic; + iss >> target; + } + return (0); +} + +//TOPIC #testtesttest :test123 + +//@time=2024-07-22T14:57:54.693Z :HoutwormNick!~HoutwormU@84-86-79-218.fixed.kpn.net TOPIC #testtesttest :test123 diff --git a/Topic.hpp b/Topic.hpp new file mode 100644 index 0000000..487eb94 --- /dev/null +++ b/Topic.hpp @@ -0,0 +1,19 @@ +#ifndef TOPIC_HPP +#define TOPIC_HPP + +#include "../ICommand.hpp" +#include + +class Topic : public ICommand +{ + private: + std::string topic; + Channel *targetChannel; + public: + Topic(); + ~Topic(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif diff --git a/UserCMD.cpp b/UserCMD.cpp new file mode 100644 index 0000000..f1ef0e1 --- /dev/null +++ b/UserCMD.cpp @@ -0,0 +1,67 @@ +#include "User.hpp" +#include "../User.hpp" +#include "../Connection.hpp" +#include "../IRC.hpp" +#include + + +UserCMD::UserCMD() {} + +UserCMD::~UserCMD() {} + +bool UserCMD::validate(const User &user, const std::string &msg) +{ + size_t pos; + size_t leng; + std::istringstream iss(msg); + std::string word; + + leng = msg.length(); + pos = msg.find(":") + 1; + this->realName = msg.substr(pos, leng - pos); + iss >> word; // should be USER + iss >> word; // should be the Nickname + this->nickName = word; + // perhaps we should check the real and username on length and illegal characters + return true; +} + +bool UserCMD::validate(const Connection &conn, const std::string &msg) +{ + size_t pos; + size_t leng; + std::istringstream iss(msg); + std::string word; + + leng = msg.length(); + pos = msg.find(":") + 1; + this->realName = msg.substr(pos, leng - pos); + iss >> word; // should be USER + iss >> word; // should be the Nickname + this->nickName = word; + return true; + // perhaps we should check the real and username on length and illegal characters +} + +int UserCMD::run(User &user, IRC::t_send_f &send) +{ + user->setUserName(this->userName); + user->setRealName(this->realName); + return (0); +} + +int UserCMD::run(Connection &conn, IRC::t_send_f &send) +{ + if (conn->getNickName()) // Nick was called before and we will create the user here + { + user = IRCManager::addUser(conn, this->userName, this->realName, conn->getNickName()); + user->setUserName(this->userName); + user->setRealName(this->realName); + } + else // User was called before Nick and User will be created in Nick + { + user->setUserName(this->userName); + user->setRealName(this->realName); + } + return (0); +} diff --git a/UserCMD.hpp b/UserCMD.hpp new file mode 100644 index 0000000..8c559bf --- /dev/null +++ b/UserCMD.hpp @@ -0,0 +1,22 @@ +#ifndef USERCMD_HPP +#define USERCMD_HPP + +#include "../ICommand.hpp" +#include "../IRC.hpp" +#include + +class UserCMD : public ICommand +{ + private: + std::string userName; + std::string realName; + public: + UserCMD(); + ~UserCMD(); + bool validate(const User &user, const std::string &msg); + bool validate(const Connection &conn, const std::string &message); + int run(User &user, IRC::t_send_f &send); + int run(Connection &conn, IRC::t_send_f &send); +}; + +#endif diff --git a/Utils.cpp b/Utils.cpp new file mode 100644 index 0000000..7fa51fa --- /dev/null +++ b/Utils.cpp @@ -0,0 +1,11 @@ +#include +#include +#include + +int main(void) +{ + std::time_t t = std::time(0); + std::tm* now = std::localtime(&t); + std::cout << std::setfill('0') << "@time=" << (now->tm_year + 1900) + "-" + std::setw(2) + (now->tm_mon + 1) + "-" + std::setw(2) + now->tm_mday + "T" + std::setw(2) + now->tm_hour + ":" + std::setw(2) + now->tm_min + ":" + std::setw(2) + now->tm_sec + "." + std::setw(3) + now->tm_msec + "Z"; + return(0); +} diff --git a/Who.cpp b/Who.cpp new file mode 100644 index 0000000..914ba1b --- /dev/null +++ b/Who.cpp @@ -0,0 +1,60 @@ +#include "Who.hpp" +#include "../IRC.hpp" +#include + +bool Who::validate(const User &user, const std::string &msg) +{ + std::istringstream iss(msg); + std::string word; + std::string current; + + iss >> word; // should be WHO + iss >> word; // should be the channel we want the userlist for + this->targetChannel = IRCManager::getChannelFromName(word); + if (this->targetChannel) + { + std::istringstream userList(this->targetChannel->getUserList()); + userList >> current; + while (current[0]) + { + if (user->getNickName() == current) + return (true); + userList >> current; + } + } + return (false); +} + +int Who::run(User &user, IRC::t_send_f &send) +{ + std::istringstream userList(this->targetChannel->getUserList()); + std::string current; + User userObj; + + send(user, ":" + IRCManager::getHostName() + " 324 " user->getNickName() + this->targetChannel->getChannelName() + "need to extract modes"; // better do this when I get Channel.hpp + send(user, ":" + IRCManager::getHostName() + " 329 " user->getNickName() + this->targetChannel->getChannelName() + "1621432263"; // not sure what this code is for, Maybe the age of the channel or something + userList >> current; + while (current[0]) + { + userObj = IRCManager::getUserFromName(current); + send(user, ":" + IRCManager::getHostName() + " 354 " user->getNickName() + " 152 " + this->targetChannel->getChannelName() + " ~" userObj->getUserName() + " " + userObj->getHostName() + " " + IRCManager::getHostName() + " " + userObj->getNickName " H 0 :" userObj->getRealName(); + userList >> current; + } + return (0); +} + + +//+n Disallows external messages. +//+t Only op/hops can set the topic. +//+p Sets the channel as invisible in /list. +//+s Sets the channel as invisible in /list and /whois. +//+i Sets the channel as closed unless the person was invited. +//+k [pass] Sets a password for the channel which users must enter to join. +//+l [number] Sets a limit on the number of users who are allowed in the channel at the same time. +//+m Prevents users who are not opped/hopped/voiced from talking. +//+R Sets the channel so only registered nicks are allowed in. +//+M Sets the channel so only registered nicks are allowed to talk. +//+S Strips formatting from messages, rendering them as plaintext. +//+c Blocks messages containing color codes. +//+i A user must be invited to join the channel. +//+N No nick changes permitted in the channel. diff --git a/Who.hpp b/Who.hpp new file mode 100644 index 0000000..4e3b055 --- /dev/null +++ b/Who.hpp @@ -0,0 +1,18 @@ +#ifndef WHO_HPP +#define WHO_HPP + +#include "../ICommand.hpp" +#include + +class Who : public ICommand +{ + private: + Channel *targetChannel; + public: + Who(); + ~Who(); + bool validate(const User &user, const std::string &msg); + int run(User &user, IRC::t_send_f &send); +}; + +#endif