-storing the channel in another file with the channel requirment and the client : it's when registerd in the irssi client with the pass and the nick and the user all this data stored in the client file and make the irssi client connecte with the server , after tha handle the join commande to make the user join a channel and handle the brodcast msg to all the clients in the channel

This commit is contained in:
mochaoui
2024-04-17 06:16:22 -05:00
parent 0399adf8e1
commit 7a54b230e3
8 changed files with 337 additions and 44 deletions

View File

@@ -7,3 +7,39 @@ Client::Client(int fd, std::string addr) : _fd(fd), _addr(addr) {}
Client::~Client() {} Client::~Client() {}
int Client::getFd() const {return _fd;} int Client::getFd() const {return _fd;}
void Client::setPassword(const std::string& password) {
pass = password;
}
std::string Client::getPassowrd() const {
return pass;
}
// Implementation of getter and setter functions for name
std::string Client::getName() const {
return name;
}
void Client::setName(const std::string& newName) {
name = newName;
}
// Implementation of getter and setter functions for nick
std::string Client::getNick() const {
return nick;
}
void Client::setNick(const std::string& newNick) {
nick = newNick;
}
// Implementation of getter and setter functions for user
std::string Client::getUser() const {
return user;
}
void Client::setUser(const std::string& newUser) {
user = newUser;
}

View File

@@ -6,6 +6,10 @@
class Client { class Client {
private: private:
int _fd; int _fd;
std::string pass;
std::string name;
std::string nick;
std::string user;
std::string _addr; std::string _addr;
bool _isRegistered; bool _isRegistered;
public: public:
@@ -14,6 +18,20 @@ class Client {
~Client(); ~Client();
int getFd() const; int getFd() const;
std::string getPassowrd() const;
void setPassword(const std::string& password); // Function to set the password
// Getter and setter for name
std::string getName() const;
void setName(const std::string& newName);
// Getter and setter for nick
std::string getNick() const;
void setNick(const std::string& newNick);
// Getter and setter for user
std::string getUser() const;
void setUser(const std::string& newUser);
}; };
#endif #endif

View File

@@ -1,6 +1,6 @@
NAME = ircserv NAME = ircserv
SRC = main.cpp Server.cpp Client.cpp SRC = main.cpp Server.cpp Client.cpp channel.cpp
OBJ = ${SRC:.cpp=.o} OBJ = ${SRC:.cpp=.o}

View File

@@ -1,4 +1,5 @@
#include "Server.hpp" #include "Server.hpp"
int a = 0;
bool Server::_signal = false; bool Server::_signal = false;
@@ -6,6 +7,14 @@ Server::Server() {}
Server::~Server() {} Server::~Server() {}
// void Server::setPassword(const std::string& password) {
// _password = password;
// }
std::string Server::getPassowrd() const {
return _password;
}
void Server::parseArgs(int ac, char **av) { void Server::parseArgs(int ac, char **av) {
if (ac != 3) if (ac != 3)
throw std::runtime_error("Usage: ./ircserv <port> <password>"); throw std::runtime_error("Usage: ./ircserv <port> <password>");
@@ -104,9 +113,12 @@ void Server::handleClientConnection() {
if (newFd == -1) { if (newFd == -1) {
throw std::runtime_error("Error: accept() failed"); throw std::runtime_error("Error: accept() failed");
} }
std::string passwordRequest = "Please enter the password:\n";
send(newFd, passwordRequest.c_str(), passwordRequest.length(), 0);
addPollfd(newFd, POLLIN, 0); addPollfd(newFd, POLLIN, 0);
_clients.push_back(Client(newFd, inet_ntoa((client_addr.sin_addr)))); _clients.push_back(Client(newFd, inet_ntoa((client_addr.sin_addr))));
std::cout << "Client <" << newFd << "> Connected" << std::endl; std::cout << "Client <" << newFd << "> Connected" << std::endl;
} }
@@ -137,17 +149,18 @@ std::string trim(const std::string& str) {
// here i create the channel and add the nicks of the users with some checks // 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) { void Server::createChannel(const std::string& channelName, const std::string& nickname, int fd) {
// Check if the channel already exists // Check if the channel already exists
if (channels.find(channelName) == channels.end()) { std::map<std::string, Channel>::iterator it = channels.find(channelName);
// Channel doesn't exist, so create it if (it == channels.end()) {
std::vector<std::string> users; // Channel doesn't exist, so create it and add the user
users.push_back(nickname); // Add the user to the channel Channel newChannel(channelName);
channels[channelName] = users; newChannel.addClient(nickname, fd);
channels.insert(std::make_pair(channelName, newChannel)); // Insert the new channel into the map
std::cout << "Channel '" << channelName << "' created by '" << nickname << "'" << std::endl; std::cout << "Channel '" << channelName << "' created by '" << nickname << "'" << std::endl;
} else { } else {
// Channel already exists, just add the user to it // Channel already exists, just add the user to it
channels[channelName].push_back(nickname); it->second.addClient(nickname, fd);
std::cout << "User '" << nickname << "' joined channel '" << channelName << "'" << std::endl; std::cout << "User '" << nickname << "' joined channel '" << channelName << "'" << std::endl;
} }
} }
@@ -173,7 +186,7 @@ void sendResponse(int fd, const std::string& message) {
const char* msg = message.c_str(); const char* msg = message.c_str();
// Get the length of the message // Get the length of the message
size_t len = strlen(msg); size_t len = strlen(msg);
// Send the message to the client // Send the message to the client
ssize_t bytesSent = send(fd, msg, len, 0); ssize_t bytesSent = send(fd, msg, len, 0);
@@ -252,26 +265,26 @@ int Server::findUserFdforkickregulars(const std::string& username) {
} }
return -1; // Return -1 if the nickname is not found return -1; // Return -1 if the nickname is not found
} }
//brodcasting msg to all nicks in the channel // brodcasting msg to all nicks in the channel
void Server::broadcastMessage(const std::string& channel, const std::string& senderNickname, const std::string& msg) { void Server::broadcastMessage(const std::string& channel, const std::string& senderNickname, const std::string& msg) {
// Check if the channel exists // Check if the channel exists
if (channels.find(channel) == channels.end()) { debugPrintChannels();
std::map<std::string, Channel>::iterator it = channels.find(channel);
if (it == channels.end()) {
std::cerr << "Channel " << channel << " does not exist" << std::endl; std::cerr << "Channel " << channel << " does not exist" << std::endl;
return; return;
} }
// Iterate through all clients in the channel and send the message // Get a reference to the vector of clients in the channel
// Get a reference to the vector of clients in the channel const std::vector<std::string>& clients = it->second.getClients();
const std::vector<std::string>& clients = channels[channel];
// Iterate over the vector using iterators // Iterate over the vector of clients and send the message to each one
std::vector<std::string>::const_iterator it; for (size_t i = 0; i < clients.size(); ++i) {
for (it = clients.begin(); it != clients.end(); ++it) {
// Get the current client nickname // Get the current client nickname
const std::string& client = *it; const std::string& client = clients[i];
// Find the file descriptor associated with the client nickname // Find the file descriptor associated with the client nickname
int recipientFd = findUserFd1(client); int recipientFd = it->second.getUserFd(client);
// If the file descriptor is found, send the message to the client // If the file descriptor is found, send the message to the client
if (recipientFd != -1) { if (recipientFd != -1) {
@@ -332,45 +345,119 @@ void Server::handleClientData(int fd) {
std::cout << "Received data from client " << fd << ": " << command << std::endl; std::cout << "Received data from client " << fd << ": " << command << std::endl;
//******************* FROM THERE IM STARTING TOP GGG ************ . //******************* FROM THERE IM STARTING TOP GGG ************ .
if (startsWith(command, "SETNICK ")) { if (startsWith(command, "pass"))
{
std::string cmd, password;
std::istringstream iss(command);
iss >> cmd >> password;
password = trim(password); // Remove leading/trailing whitespace
std::string passwordoftheserver = getPassowrd();
if (passwordoftheserver != password)
{
std::string errorMessage = "Error: Incorrect password\n";
send(fd, errorMessage.c_str(), errorMessage.length(), 0);
}
else {
std::string confirmation = "Welcome sir\n";
send(fd, confirmation.c_str(), confirmation.length(), 0);
a = 1;
}
// for (size_t i = 0; i < _clients.size(); ++i) {
// if (_clients[i].getFd() == fd) {
// _clients[i].setPassword(password);
// std::cout << "Password set for client " << fd << ": " << password << std::endl;
// break;
// }
// }
}
if (startsWith(command, "nick")) {
std::string cmd, nick;
std::istringstream iss(command);
iss >> cmd >> nick;
nick = trim(nick);
for (size_t i = 0; i < _clients.size(); ++i) {
if (_clients[i].getFd() == fd) {
_clients[i].setNick(nick);
std::cout << "Password set for client " << fd << ": " << nick << std::endl;
break;
}
}
// Extract the nickname from the command // Extract the nickname from the command
std::string nickname = command.substr(8); // Assuming "/setnick " is 9 characters long // std::string nickname = command.substr(8); // Assuming "/setnick " is 9 characters long
// Handle setting the nickname for the client's connection // Handle setting the nickname for the client's connection
setNickname(fd, nickname);
// Send a response back to the client confirming the action // Send a response back to the client confirming the action
sendResponse(fd, "Nickname set to: " + nickname + '\n'); sendResponse(fd, "Nickname set to: " + nick + '\n');
} else if (startsWith(command, "SETUSER ")) { a = 2;
} else if (startsWith(command, "user")) {
std::istringstream iss(command); std::istringstream iss(command);
std::string cmd, username, privilege_level; std::string cmd, username, dontworry, dontworry1, realname, nickname;
iss >> cmd >> username; iss >> cmd >> username >> dontworry >> dontworry1 >> realname;
// Remove leading and trailing whitespace from parameters
username = trim(username); username = trim(username);
std::getline(iss, privilege_level); dontworry = trim(dontworry);
privilege_level = trim(privilege_level); dontworry1 = trim(dontworry1);
std::cout << "this is the privilege : " << privilege_level << std::endl; realname = trim(realname);
if (privilege_level == "operator" ) for (size_t i = 0; i < _clients.size(); ++i) {
{ if (_clients[i].getFd() == fd) {
//si moskir hna atbda lkhdma dyalk _clients[i].setUser(username);
// std::cout << "we need to handle this " << std::endl; _clients[i].setName(realname);
setUsernameoperators(fd, username); nickname = _clients[i].getNick();
sendResponse(fd, "Username set to: " + username + " with privilege_level : " + privilege_level + '\n'); break;
}
} }
else if (privilege_level == "regular") {
setUsernameregular(fd, username);
sendResponse(fd, "Username set to: " + username + " with privilege_level : " + privilege_level + '\n');
} sendResponse(fd, "username set to: " + username + '\n');
sendResponse(fd, "realname set to: " + realname + '\n');
std::string one = ":irc.topg 001 " + nickname + " :Welcome to the topg Network, " + nickname + '\n';
std::string two = ":irc.topg 002 " + nickname + " :Your host is topg, running version 3030" + '\n';
std::string tre = ":irc.topg 003 " + nickname + " :This server was created Tue Nov 30 2011 at 11:11:25 EET" + '\n';
std::string foor = ":irc.topg 004 " + nickname + " topg tella(enterprise)-2.3(12)-netty(5.4c)-proxy(0.9) oOiwscrknfbghexzSjFI bhijklmMnoOstvcdSuU bkohv" + '\n';
send(fd, one.c_str(), one.length(), 0);
send(fd, two.c_str(), two.length(), 0);
send(fd, tre.c_str(), tre.length(), 0);
send(fd, foor.c_str(), foor.length(), 0);
// if (privilege_level == "operator" )
// {
// //si moskir hna atbda lkhdma dyalk
// // std::cout << "we need to handle this " << std::endl;
// setUsernameoperators(fd, username);
// sendResponse(fd, "Username set to: " + username + " with privilege_level : " + privilege_level + '\n');
// }
// else if (privilege_level == "regular") {
// setUsernameregular(fd, username);
// sendResponse(fd, "Username set to: " + username + " with privilege_level : " + privilege_level + '\n');
// }
// Process other commands or messages // Process other commands or messages
// processCommand(fd, command); // processCommand(fd, command);
} else if (startsWith(command, "JOIN ")) { } else if (startsWith(command, "JOIN ")) {
std::string chanelname = command.substr(5); std::string user;
for (size_t i = 0; i < _clients.size(); ++i) {
if (_clients[i].getFd() == fd) {
user = _clients[i].getUser();
break;
}
}
std::string chanelname = command.substr(6);
chanelname = trim(chanelname); chanelname = trim(chanelname);
createChannel(chanelname, nicknames[fd]); createChannel(chanelname, user, fd);
} else if (startsWith(command, "PRIVMSG ")) { } else if (startsWith(command, "PRIVMSG ")) {
// Extract the recipient and the message from the command // Extract the recipient and the message from the command
@@ -425,7 +512,7 @@ void Server::handleClientData(int fd) {
} }
else if (startsWith(command, "KICK ")) else if (startsWith(command, "KICK "))
sendResponse(fd, "Error: You don't have permission to use this command.\n"); sendResponse(fd, "Error: You don't have permission to use this command.\n");
//**************** STOOOOOOP HERE TOP G ... //**************** STOOOOOOP HERE TOP G ...
break; break;
} }

View File

@@ -16,6 +16,7 @@
#include "Client.hpp" #include "Client.hpp"
#include <cstring> #include <cstring>
#include <map> #include <map>
#include "channel.hpp"
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
@@ -31,7 +32,8 @@ class Server {
std::map<int, std::string> nicknames; // Replace unordered_map with map std::map<int, std::string> nicknames; // Replace unordered_map with map
std::map<int, std::string> usernamesoperators; // Replace unordered_map with map std::map<int, std::string> usernamesoperators; // Replace unordered_map with map
std::map<int, std::string> usernamesregulars; std::map<int, std::string> usernamesregulars;
std::map<std::string, std::vector<std::string> > channels; //here a chanel name and list of client in every chanel // std::map<std::string, std::vector<std::string> > channels; //here a chanel name and list of client in every chanel
std::map<std::string, Channel> channels;
@@ -40,9 +42,11 @@ class Server {
~Server(); ~Server();
// THAT'S MY FUNCTIONS START FROM THERE // THAT'S MY FUNCTIONS START FROM THERE
void setNickname(int fd, const std::string& nickname); void setNickname(int fd, const std::string& nickname);
std::string getPassowrd() const;
void setPassword(const std::string& password);
void setUsernameoperators(int fd, const std::string& username); void setUsernameoperators(int fd, const std::string& username);
void setUsernameregular(int fd, const std::string& username); void setUsernameregular(int fd, const std::string& username);
void createChannel(const std::string& channel, const std::string& nickname); 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 handlePrivateMessage(int senderFd, const std::string& recipient, const std::string& message);
void broadcastMessage(const std::string& channel, const std::string& senderNickname, const std::string& msg); void broadcastMessage(const std::string& channel, const std::string& senderNickname, const std::string& msg);
int findUserFd1(const std::string& nickname); int findUserFd1(const std::string& nickname);
@@ -62,6 +66,14 @@ class Server {
void handleClientData(int fd); void handleClientData(int fd);
void clientCleanup(int fd); void clientCleanup(int fd);
void closeFds(); void closeFds();
void debugPrintChannels() {
std::cout << "List of channels:" << std::endl;
std::map<std::string, Channel>::iterator it;
for (it = channels.begin(); it != channels.end(); ++it) {
std::cout << "- " << it->first << std::endl; // Print the channel name (it->first)
}
}
}; };
#endif #endif

0
channel.cpp Normal file
View File

96
channel.hpp Normal file
View File

@@ -0,0 +1,96 @@
#ifndef CHANNEL_HPP
#define CHANNEL_HPP
#include <sstream>
#include <algorithm>
#include <cctype>
#include <unistd.h> // Include for the send function
#include <cstring> // Include for the strlen function
#include <iostream>
#include <cstdlib>
#include <csignal>
#include <arpa/inet.h>
#include <fcntl.h>
#include <vector>
#include <poll.h>
#include "Client.hpp"
#include <cstring>
#include <map>
class Channel {
private:
std::string Channelname;
std::string topic;
std::string key;
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::vector<std::string> operators;
public:
// Constructors
Channel(const std::string& name) : Channelname(name) {}
// Destructor
~Channel() {}
// Add a client to the channel
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
}
// Add an operator to the channel
void addOperator(const std::string& operatorName) {
operators.push_back(operatorName);
}
int getUserFd(const std::string& username) const {
std::map<std::string, int>::const_iterator it = userFdMap.find(username);
if (it != userFdMap.end()) {
return it->second;
}
return -1; // Return -1 if username not found
}
// Get all clients' usernames in the channel
std::vector<std::string> getClients() const {
std::vector<std::string> clients;
std::map<std::string, int>::const_iterator it;
for (it = userFdMap.begin(); it != userFdMap.end(); ++it) {
clients.push_back(it->first);
}
return clients;
}
// Remove an operator from the channel
};
#endif

44
todo.txt Normal file
View File

@@ -0,0 +1,44 @@
remember the quote commande
create object for each instence : channel and client and server
client : fd , pass ,name , nick , user , and remember the lastchannel *
channel : _limite : it's limite of the users joined the channel
-> nameofchannel
->topic
->key
->hastopic haskey and creationtime : if created .
->victor of clients
->vicotr of invited users
->victor of operators
//tpic seter .
//tpic time .
this if for testing this how the commande behav : /connect liberachat
////remember this when you connect to irssi you need to prompte the client to put a password
//remmember the username have 4 parameter check rfc
after seting the data , password user , nick ---> responce 001, 002, 003, 004
and make sure the irssi client need all the responce to recognized you as a server be awake
rmreconns
window close