finish the topic commande and the invite commande
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -49,6 +49,8 @@
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"map": "cpp",
|
||||
"sstream": "cpp"
|
||||
"sstream": "cpp",
|
||||
"ctime": "cpp",
|
||||
"iomanip": "cpp"
|
||||
}
|
||||
}
|
177
Server.cpp
177
Server.cpp
@@ -149,6 +149,30 @@ std::string trim(const std::string& str) {
|
||||
return str.substr(first, last - first + 1);
|
||||
}
|
||||
|
||||
std::string formatCreationTime() {
|
||||
// Get the current time
|
||||
std::time_t currentTime = std::time(NULL);
|
||||
// Convert the current time to tm struct for easier manipulation
|
||||
std::tm* localTime = std::localtime(¤tTime);
|
||||
|
||||
// Format the time string manually
|
||||
char buffer[80]; // Buffer to hold the formatted time string
|
||||
std::strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", localTime);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
|
||||
std::string constructCreationTimeMessage(const std::string& channelName) {
|
||||
std::stringstream ss;
|
||||
ss << "Channel #" << channelName << " created " << formatCreationTime();
|
||||
return ss.str();
|
||||
}
|
||||
std::string constructJoinedTimeMessage(const std::string& channelName) {
|
||||
std::stringstream ss;
|
||||
ss << "Channel #" << channelName << " Joined " << formatCreationTime();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
// here i create the channel and add the nicks of the users with some checks
|
||||
void Server::createChannel(const std::string& channelName, const std::string& nickname, int fd) {
|
||||
@@ -164,6 +188,7 @@ void Server::createChannel(const std::string& channelName, const std::string& ni
|
||||
// Send JOIN message to the client
|
||||
std::string joinMessage = ":" + nickname + " JOIN #" + channelName + "\n";
|
||||
send(fd, joinMessage.c_str(), joinMessage.length(), 0);
|
||||
|
||||
// Send MODE message to the client
|
||||
std::string modeMessage = ":irc.example.com MODE #" + channelName + " +nt\n";
|
||||
send(fd, modeMessage.c_str(), modeMessage.length(), 0);
|
||||
@@ -176,30 +201,34 @@ void Server::createChannel(const std::string& channelName, const std::string& ni
|
||||
std::string endOfNamesMessage = ":irc.example.com 366 " + nickname + " #" + channelName + " :End of /NAMES list.\n";
|
||||
send(fd, endOfNamesMessage.c_str(), endOfNamesMessage.length(), 0);
|
||||
|
||||
std::string creationTimeMessage = constructCreationTimeMessage(channelName);
|
||||
std::string channelMessage = ":irc.example.com 354 " + channelName + " " + creationTimeMessage + "\n";
|
||||
send(fd, channelMessage.c_str(), channelMessage.length(), 0);
|
||||
|
||||
// Insert the new channel into the map
|
||||
channels.insert(std::make_pair(channelName, newChannel));
|
||||
|
||||
} else {
|
||||
// Channel already exists, just add the user to it
|
||||
it->second.addClient(nickname, fd);
|
||||
std::string operators = channels[channelName].getOperatorNickname(opperatorfd);
|
||||
|
||||
// Send JOIN message to the client
|
||||
std::string joinMessage = ":" + nickname + " JOIN #" + channelName + "\n";
|
||||
send(fd, joinMessage.c_str(), joinMessage.length(), 0);
|
||||
|
||||
// Send CHANNEL TOPIC message to the client
|
||||
std::string topicMessage = ":irc.example.com 332 " + nickname + " #" + channelName + " :This is my cool channel! https://irc.com\n";
|
||||
std::cout << "this is the topi and he good : "<< channels[channelName].getTopic() << std::endl;
|
||||
std::string topicMessage = ":irc.example.com 332 " + nickname + " #" + channelName + " :" + channels[channelName].getTopic() + " https://irc.com\n";
|
||||
send(fd, topicMessage.c_str(), topicMessage.length(), 0);
|
||||
|
||||
// Send CHANNEL CREATION TIME message to the client
|
||||
std::string creationTimeMessage = ":irc.example.com 333 " + nickname + " #" + channelName + " dan!~d@localhost 1547691506\n";
|
||||
send(fd, creationTimeMessage.c_str(), creationTimeMessage.length(), 0);
|
||||
|
||||
// Send NAMES message to the client
|
||||
std::string namesMessage = ":irc.example.com 353 " + nickname + " @ #" + channelName + " :";
|
||||
|
||||
const std::vector<std::string>& clients = channels[channelName].getClients();
|
||||
std::string operators = channels[channelName].getOperatorNickname(opperatorfd);
|
||||
|
||||
|
||||
for (size_t i = 0; i < clients.size(); ++i) {
|
||||
const std::string& user = clients[i];
|
||||
@@ -219,6 +248,12 @@ void Server::createChannel(const std::string& channelName, const std::string& ni
|
||||
// Send END OF NAMES message to the client
|
||||
std::string endOfNamesMessage = ":irc.example.com 366 " + nickname + " #" + channelName + " :End of /NAMES list.\n";
|
||||
send(fd, endOfNamesMessage.c_str(), endOfNamesMessage.length(), 0);
|
||||
|
||||
std::string creationTimeMessage = constructJoinedTimeMessage(channelName);
|
||||
std::string channelMessage = ":irc.example.com 354 " + channelName + " " + creationTimeMessage + "\n";
|
||||
send(fd, channelMessage.c_str(), channelMessage.length(), 0);
|
||||
|
||||
smallbroadcastMessageforjoin(nickname, channelName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,6 +343,24 @@ void Server::handlePrivateMessage(int senderFd, const std::string& recipient, co
|
||||
}
|
||||
}
|
||||
|
||||
void Server::handleInvitation(int senderFd, const std::string& recipient, std::string channelName) {
|
||||
// Find the recipient's connection (socket file descriptor)
|
||||
int recipientFd = findUserFd1(recipient);
|
||||
// std::string sendernameuser = findUsernameforsending(senderFd);
|
||||
|
||||
if (recipientFd != -1) {
|
||||
// Construct the invitation message
|
||||
std::string inviteMessage = ":" + nicknames[senderFd] + " INVITE " + recipient + " :#" + channelName + "\r\n";
|
||||
|
||||
// Send the invitation message to the recipient
|
||||
send(recipientFd, inviteMessage.c_str(), inviteMessage.length(), 0);
|
||||
} else {
|
||||
// Handle case where recipient is not found (e.g., user not online)
|
||||
std::string errorMessage = ":server.host NOTICE " + nicknames[senderFd] + " :Error: User '" + recipient + "' not found or offline\r\n";
|
||||
send(senderFd, errorMessage.c_str(), errorMessage.length(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
//this find is for finding nickname of the users i need to brodcasting to
|
||||
int Server::findUserFd1(const std::string& username) {
|
||||
std::map<int, std::string>::iterator it;
|
||||
@@ -378,20 +431,11 @@ void Server::broadcastMessage(const std::string& channel, const std::string& sen
|
||||
}
|
||||
|
||||
void Server::smallbroadcastMessagefortheckick(std::string nicknamesender , const std::string& channelname, const std::string& usertokick, const std::string& reason) {
|
||||
// Check if the channel exists
|
||||
std::map<std::string, Channel>::iterator it = channels.find(channelname);
|
||||
if (it == channels.end()) {
|
||||
std::cerr << "Channel " << channelname << " does not exist" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// if (channels[channelname].findUserFdForKickRegulars(nicknamesender) == -1)
|
||||
// {
|
||||
// std::cout << "this user kicked from the channel" << std::endl;
|
||||
// return;
|
||||
// }
|
||||
// Construct the IRC message with the correct format for broadcasting
|
||||
// std::string message = ":" + senderNickname + " PRIVMSG #" + channel + " :" + msg + "\r\n";
|
||||
std::string kickMessage = ":" + nicknamesender + " KICK #" + channelname + " " + usertokick + " :" + reason + "\n";
|
||||
|
||||
// Get a reference to the vector of clients in the channel
|
||||
@@ -402,28 +446,78 @@ void Server::smallbroadcastMessagefortheckick(std::string nicknamesender , const
|
||||
// Get the current client nickname
|
||||
const std::string& client = clients[i];
|
||||
|
||||
// Skip sending the message to the sender
|
||||
// std::cout << "this is the client name : "<< client << std::endl;
|
||||
// std::cout << "this is the nickname name : " << senderNickname << std::endl;
|
||||
|
||||
if (client == nicknamesender) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the file descriptor associated with the client nickname
|
||||
int recipientFd = it->second.getUserFd(client);
|
||||
|
||||
// If the file descriptor is found, send the message to the client
|
||||
if (recipientFd != -1) {
|
||||
// std::cout << message << std::endl;
|
||||
send(recipientFd, kickMessage.c_str(), kickMessage.size(), 0);
|
||||
} else {
|
||||
// If the file descriptor is not found, print an error message
|
||||
std::cerr << "Client " << client << " not found" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Server::smallbroadcastMessageforjoin(std::string nicknamesender , const std::string& channelname) {
|
||||
std::map<std::string, Channel>::iterator it = channels.find(channelname);
|
||||
if (it == channels.end()) {
|
||||
std::cerr << "Channel " << channelname << " does not exist" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::string joinMessage = ":" + nicknamesender + " JOIN #" + channelname + "\n";
|
||||
|
||||
// Get a reference to the vector of clients in the channel
|
||||
const std::vector<std::string>& clients = it->second.getClients();
|
||||
|
||||
// Iterate over the vector of clients and send the message to each one
|
||||
for (size_t i = 0; i < clients.size(); ++i) {
|
||||
// Get the current client nickname
|
||||
const std::string& client = clients[i];
|
||||
|
||||
if (client == nicknamesender) {
|
||||
continue;
|
||||
}
|
||||
int recipientFd = it->second.getUserFd(client);
|
||||
if (recipientFd != -1) {
|
||||
send(recipientFd, joinMessage.c_str(), joinMessage.size(), 0);
|
||||
} else {
|
||||
std::cerr << "Client " << client << " not found" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Server::smallbroadcastMessageforTopic(std::string nicknamesender, const std::string& channelname, std::string topic) {
|
||||
std::map<std::string, Channel>::iterator it = channels.find(channelname);
|
||||
if (it == channels.end()) {
|
||||
std::cerr << "Channel " << channelname << " does not exist" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct the topic message
|
||||
std::string topicMessage = ":" + nicknamesender + " TOPIC #" + channelname + " :" + topic + "\n";
|
||||
|
||||
// Get a reference to the vector of clients in the channel
|
||||
const std::vector<std::string>& clients = it->second.getClients();
|
||||
|
||||
// Iterate over the vector of clients and send the message to each one
|
||||
for (size_t i = 0; i < clients.size(); ++i) {
|
||||
// Get the current client nickname
|
||||
const std::string& client = clients[i];
|
||||
|
||||
if (client == nicknamesender) {
|
||||
continue;
|
||||
}
|
||||
int recipientFd = it->second.getUserFd(client);
|
||||
if (recipientFd != -1) {
|
||||
send(recipientFd, topicMessage.c_str(), topicMessage.size(), 0);
|
||||
} else {
|
||||
std::cerr << "Client " << client << " not found" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//check if ope or not
|
||||
@@ -671,6 +765,43 @@ void Server::handleClientData(int fd) {
|
||||
std::string errorMessage = ":" + channels[channelName].getNickname(fd) + " PRIVMSG #" + channelName + " :Error: You are not authorized to execute this command " + userToKick + "\r\n";
|
||||
send(fd, errorMessage.c_str(), errorMessage.size(), 0); }
|
||||
}
|
||||
else if (startsWith(command, "TOPIC ")){
|
||||
std::string channelName, topic;
|
||||
std::istringstream iss(command.substr(7));
|
||||
iss >> channelName;
|
||||
std::getline(iss, topic);
|
||||
channelName = trim(channelName);
|
||||
topic = trim(topic);
|
||||
topic = topic.substr(1);
|
||||
|
||||
if (channels.find(channelName) != channels.end() && channels[channelName].isOperator(fd))
|
||||
{
|
||||
channels[channelName].setTopic(topic);
|
||||
smallbroadcastMessageforTopic(channels[channelName].getNickname(fd), channelName, topic );
|
||||
} else {
|
||||
std::string errorMessage = ":" + channels[channelName].getNickname(fd) + " PRIVMSG #" + channelName + " :Error: You are not authorized to execute this command " + "\r\n";
|
||||
send(fd, errorMessage.c_str(), errorMessage.size(), 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (startsWith(command, "INVITE "))
|
||||
{
|
||||
std::string channelName, nickname;
|
||||
std::istringstream iss(command.substr(7));
|
||||
iss >> nickname >> channelName;
|
||||
channelName = trim(channelName);
|
||||
nickname = trim(nickname);
|
||||
channelName = channelName.substr(1);
|
||||
if (channels.find(channelName) != channels.end() && channels[channelName].isOperator(fd))
|
||||
{
|
||||
channels[channelName].addClientinveted(nickname, fd);
|
||||
handleInvitation(fd, nickname, channelName);
|
||||
} else {
|
||||
std::string errorMessage = ":" + channels[channelName].getNickname(fd) + " PRIVMSG #" + channelName + " :Error: You are not authorized to execute this command " + "\r\n";
|
||||
send(fd, errorMessage.c_str(), errorMessage.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
//**************** STOOOOOOP HERE TOP G ...
|
||||
break;
|
||||
|
@@ -17,6 +17,9 @@
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include "channel.hpp"
|
||||
#include <ctime>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
|
||||
@@ -48,12 +51,15 @@ class Server {
|
||||
void setPassword(const std::string& password);
|
||||
void setUsernameoperators(int fd, const std::string& username);
|
||||
void setUsernames(int fd, const std::string& username);
|
||||
|
||||
std::string formatCreationTime();
|
||||
void setUsernameregular(int fd, const std::string& username);
|
||||
void createChannel(const std::string& channel, const std::string& nickname, int fd);
|
||||
void handlePrivateMessage(int senderFd, const std::string& recipient, const std::string& message);
|
||||
void handleInvitation(int senderFd, const std::string& recipient, std::string channelName);
|
||||
void broadcastMessage(const std::string& channel, const std::string& senderNickname, const std::string& msg, int fd);
|
||||
void smallbroadcastMessagefortheckick(std::string nicknamesender , const std::string& channelname, const std::string& usertokick, const std::string& reason);
|
||||
void smallbroadcastMessageforjoin(std::string nicknamesender , const std::string& channelname);
|
||||
void smallbroadcastMessageforTopic(std::string nicknamesender, const std::string& channelname, std::string topic);
|
||||
int findUserFd1(const std::string& username);
|
||||
std::string findUsernameforsending(int fd);
|
||||
bool isOperator(int fd);
|
||||
|
32
channel.hpp
32
channel.hpp
@@ -27,7 +27,7 @@ private:
|
||||
std::vector<std::string> users;
|
||||
// std::map<int, std::string> nicknames; // Replace unordered_map with map
|
||||
std::map<std::string, int> userFdMap; // Mapping of usernames to file descriptors
|
||||
std::vector<std::string> invitedUsers;
|
||||
std::map<std::string, int> invitedUsers;
|
||||
std::map<std::string, int> operators;
|
||||
|
||||
public:
|
||||
@@ -39,34 +39,24 @@ public:
|
||||
// Destructor
|
||||
~Channel() {}
|
||||
|
||||
// Add a client to the channel
|
||||
|
||||
|
||||
void setTopic(const std::string& newTopic) {
|
||||
topic = newTopic;
|
||||
}
|
||||
|
||||
// Get topic function
|
||||
std::string getTopic() const {
|
||||
return topic;
|
||||
|
||||
}
|
||||
|
||||
void addClient(const std::string& client, int fd) {
|
||||
userFdMap[client] = fd;
|
||||
}
|
||||
|
||||
void addClient(const std::string& client) {
|
||||
users.push_back(client);
|
||||
}
|
||||
|
||||
// Remove a client from the channel
|
||||
void removeClient(const std::string& nickname) {
|
||||
// Implement removal logic
|
||||
// Iterate through clients vector, find the client by nickname, and remove it
|
||||
}
|
||||
|
||||
// Add an invited user to the channel
|
||||
void inviteUser(const std::string& user) {
|
||||
invitedUsers.push_back(user);
|
||||
}
|
||||
|
||||
// Remove an invited user from the channel
|
||||
void uninviteUser(const std::string& user) {
|
||||
// Implement removal logic
|
||||
// Iterate through invitedUsers vector, find the user, and remove it
|
||||
void addClientinveted(const std::string& client, int fd) {
|
||||
invitedUsers[client] = fd;
|
||||
}
|
||||
|
||||
// Add an operator to the channel
|
||||
|
Reference in New Issue
Block a user