I broke something with displaying the clients input plainly
This commit is contained in:
parent
b2c5e0f5d7
commit
bfe88daf3e
10 changed files with 292 additions and 186 deletions
33
Makefile
33
Makefile
|
|
@ -1,14 +1,14 @@
|
||||||
# **************************************************************************** #
|
#******************************************************************************#
|
||||||
# #
|
# #
|
||||||
# ::: :::::::: #
|
# ::: :::::::: #
|
||||||
# Makefile :+: :+: :+: #
|
# Makefile :+: :+: :+: #
|
||||||
# +:+ +:+ +:+ #
|
# +:+ +:+ +:+ #
|
||||||
# By: sben-tay <sben-tay@student.42.fr> +#+ +:+ +#+ #
|
# By: omoudni <omoudni@student.42paris.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2025/05/02 15:40:00 by rparodi #+# #+# #
|
# Created: 2025/05/02 15:40:00 by rparodi #+# #+# #
|
||||||
# Updated: 2025/05/21 13:01:09 by rparodi ### ########.fr #
|
# Updated: 2025/05/21 21:51:13 by omoudni ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
#******************************************************************************#
|
||||||
|
|
||||||
|
|
||||||
# Name
|
# Name
|
||||||
|
|
@ -30,7 +30,7 @@ SRC = sources/core/logs.cpp \
|
||||||
sources/core/parser.cpp \
|
sources/core/parser.cpp \
|
||||||
sources/core/main.cpp \
|
sources/core/main.cpp \
|
||||||
sources/core/Server.cpp \
|
sources/core/Server.cpp \
|
||||||
sources/user/user.cpp \
|
sources/core/user.cpp \
|
||||||
sources/channel/channel.cpp
|
sources/channel/channel.cpp
|
||||||
|
|
||||||
INC_DIR = include/core \
|
INC_DIR = include/core \
|
||||||
|
|
@ -85,30 +85,37 @@ debug: CXXFLAGS += -g
|
||||||
# debug: CXXFLAGS += -fsanitize=address
|
# debug: CXXFLAGS += -fsanitize=address
|
||||||
debug: re
|
debug: re
|
||||||
|
|
||||||
|
PORT ?= 4243
|
||||||
|
|
||||||
test: debug
|
test: debug
|
||||||
@printf '$(GREY) now running with\n\t- Port:\t\t$(GREEN)4243$(GREY)\n\t- Password:\t$(GREEN)irc$(END)\n'
|
@printf '$(GREY) now running with\n\t- Port:\t\t$(GREEN)$(PORT)$(GREY)\n\t- Password:\t$(GREEN)irc$(END)\n'
|
||||||
@if tmux has-session -t $(SESSION) 2>/dev/null; then \
|
@if tmux has-session -t $(SESSION) 2>/dev/null; then \
|
||||||
tmux kill-session -t $(SESSION); \
|
tmux kill-session -t $(SESSION); \
|
||||||
fi
|
fi
|
||||||
@tmux new-session -d -s $(SESSION) \
|
@tmux new-session -d -s $(SESSION) \
|
||||||
'bash -lc "./$(NAME) 4243 irc; exec bash"'
|
'bash -lc "./$(NAME) $(PORT) irc; exec bash"'
|
||||||
@tmux split-window -h -p 70 -t $(SESSION):0 \
|
@tmux split-window -h -p 70 -t $(SESSION):0 \
|
||||||
'bash -lc "irssi -c localhost -p 4243 -w irc || exec yes \"irssi exit code: $?\""'
|
'bash -lc "irssi -c localhost -p $(PORT) -w irc || exec yes \"irssi exit code: $?\""'
|
||||||
@tmux split-window -v -p 50 -t $(SESSION):0.1 \
|
@tmux split-window -v -p 50 -t $(SESSION):0.1 \
|
||||||
'bash -lc "nc localhost 4243 || exec yes \"netcat exit code: $?\""'
|
'bash -lc "nc localhost $(PORT) || exec yes \"netcat exit code: $?\""'
|
||||||
|
@tmux split-window -v -p 50 -t $(SESSION):0.2 \
|
||||||
|
'bash -lc "nc localhost $(PORT) || exec yes \"netcat exit code: $?\""'
|
||||||
|
@tmux split-window -v -p 50 -t $(SESSION):0.3 \
|
||||||
|
'bash -lc "nc localhost $(PORT) || exec yes \"netcat exit code: $?\""'
|
||||||
@tmux attach -t $(SESSION)
|
@tmux attach -t $(SESSION)
|
||||||
|
|
||||||
|
|
||||||
run: re
|
run: re
|
||||||
@printf '$(GREY) now running with\n\t- Port:\t\t$(GREEN)4243$(GREY)\n\t- Password:\t$(GREEN)irc$(END)\n'
|
@printf '$(GREY) now running with\n\t- Port:\t\t$(GREEN)$(PORT)$(GREY)\n\t- Password:\t$(GREEN)irc$(END)\n'
|
||||||
@if tmux has-session -t $(SESSION) 2>/dev/null; then \
|
@if tmux has-session -t $(SESSION) 2>/dev/null; then \
|
||||||
tmux kill-session -t $(SESSION); \
|
tmux kill-session -t $(SESSION); \
|
||||||
fi
|
fi
|
||||||
@tmux new-session -d -s $(SESSION) \
|
@tmux new-session -d -s $(SESSION) \
|
||||||
'bash -lc "./$(NAME) 4243 irc; exec bash"'
|
'bash -lc "./$(NAME) $(PORT) irc; exec bash"'
|
||||||
@tmux split-window -h -p 70 -t $(SESSION):0 \
|
@tmux split-window -h -p 70 -t $(SESSION):0 \
|
||||||
'bash -lc "irssi -c localhost -p 4243 -w irc || exec yes \"irssi exit code: $?\""'
|
'bash -lc "irssi -c localhost -p $(PORT) -w irc || exec yes \"irssi exit code: $?\""'
|
||||||
@tmux split-window -v -p 50 -t $(SESSION):0.1 \
|
@tmux split-window -v -p 50 -t $(SESSION):0.1 \
|
||||||
'bash -lc "nc localhost 4243 || exec yes \"netcat exit code: $?\""'
|
'bash -lc "nc localhost $(PORT) || exec yes \"netcat exit code: $?\""'
|
||||||
@tmux attach -t $(SESSION)
|
@tmux attach -t $(SESSION)
|
||||||
|
|
||||||
# Header
|
# Header
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class Server {
|
||||||
- _password : string
|
- _password : string
|
||||||
- _server_fd : int
|
- _server_fd : int
|
||||||
- _poll : PollManager
|
- _poll : PollManager
|
||||||
|
- _users : map<int, User>
|
||||||
|
|
||||||
+ Server(port : int, password : string)
|
+ Server(port : int, password : string)
|
||||||
+ start() : void
|
+ start() : void
|
||||||
|
|
@ -25,12 +26,11 @@ class Server {
|
||||||
' ============================
|
' ============================
|
||||||
class PollManager {
|
class PollManager {
|
||||||
- _fds : vector<pollfd>
|
- _fds : vector<pollfd>
|
||||||
- _users : map<int, User>
|
|
||||||
|
|
||||||
+ addUser(fd : int) : void
|
+ addUser(fd : int) : void
|
||||||
+ removeUser(fd : int) : void
|
+ removeUser(fd : int) : void
|
||||||
+ updateUser(fd : int, events : short) : void
|
+ updateUser(fd : int, events : short) : void
|
||||||
+ pollLoop(server_fd : int) : void
|
+ pollLoop(server_fd : int, newClients : std::vector<int>, disconnected : std::vector<int>) : void
|
||||||
+ readFromUser(fd : int) : void
|
+ readFromUser(fd : int) : void
|
||||||
+ writeToUser(fd : int) : void
|
+ writeToUser(fd : int) : void
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* PollManager.hpp :+: :+: :+: */
|
/* PollManager.hpp :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: sben-tay <sben-tay@student.42.fr> +#+ +:+ +#+ */
|
/* By: omoudni <omoudni@student.42paris.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/05/19 19:15:13 by omoudni #+# #+# */
|
/* Created: 2025/05/19 19:15:13 by omoudni #+# #+# */
|
||||||
/* Updated: 2025/05/20 17:22:59 by sben-tay ### ########.fr */
|
/* Updated: 2025/05/21 21:34:20 by omoudni ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
@ -16,19 +16,17 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class PollManager {
|
class PollManager
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
PollManager();
|
PollManager();
|
||||||
~PollManager();
|
~PollManager();
|
||||||
|
|
||||||
void addClient(int fd);
|
void addClient(short unsigned fd);
|
||||||
void removeClient(int fd);
|
void removeClient(short unsigned fd);
|
||||||
void updateServer(int fd);
|
void updateServer(short unsigned fd);
|
||||||
void pollLoop(int server_fd);
|
void pollLoop(int server_fd, std::vector<int> &newClients, std::vector<int> &disconnected, std::vector<std::pair<int, std::string> > &readyClients);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::vector<struct pollfd> _fds;
|
std::vector<struct pollfd> _fds;
|
||||||
std::map<int, std::string> _buffers;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* core.hpp :+: :+: :+: */
|
/* core.hpp :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: sben-tay <sben-tay@student.42.fr> +#+ +:+ +#+ */
|
/* By: omoudni <omoudni@student.42paris.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/05/12 14:16:03 by rparodi #+# #+# */
|
/* Created: 2025/05/12 14:16:03 by rparodi #+# #+# */
|
||||||
/* Updated: 2025/05/20 17:23:41 by sben-tay ### ########.fr */
|
/* Updated: 2025/05/21 21:18:22 by omoudni ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
@ -30,6 +30,11 @@ enum e_state {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// INCLUDES (not to repeat)
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include "user.hpp"
|
||||||
#include "PollManager.hpp"
|
#include "PollManager.hpp"
|
||||||
#include "color.hpp"
|
#include "color.hpp"
|
||||||
#include "server.hpp"
|
#include "server.hpp"
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,28 @@
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* server.hpp :+: :+: :+: */
|
/* server.hpp :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
/* By: omoudni <omoudni@student.42paris.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/05/20 21:50:32 by rparodi #+# #+# */
|
/* Created: 2025/05/20 21:50:32 by rparodi #+# #+# */
|
||||||
/* Updated: 2025/05/21 13:03:01 by rparodi ### ########.fr */
|
/* Updated: 2025/05/21 21:19:47 by omoudni ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "core.hpp"
|
||||||
#include "PollManager.hpp"
|
|
||||||
|
|
||||||
|
class User;
|
||||||
class Server {
|
class Server {
|
||||||
private:
|
private:
|
||||||
int _port;
|
int _port;
|
||||||
int _serverFd;
|
int _serverFd;
|
||||||
std::string _password;
|
std::string _password;
|
||||||
PollManager _pollManager;
|
PollManager _pollManager;
|
||||||
|
std::map<int, User*> _users;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Server(int port, const std::string &password);
|
Server(int port, const std::string &password);
|
||||||
~Server();
|
~Server();
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,35 @@
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* user.hpp :+: :+: :+: */
|
/* user.hpp :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
/* By: omoudni <omoudni@student.42paris.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/05/20 21:57:49 by rparodi #+# #+# */
|
/* Created: 2025/05/20 21:57:49 by rparodi #+# #+# */
|
||||||
/* Updated: 2025/05/20 22:13:41 by rparodi ### ########.fr */
|
/* Updated: 2025/05/21 21:16:56 by omoudni ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "core.hpp"
|
||||||
#include <iostream>
|
|
||||||
#include "color.hpp"
|
|
||||||
|
|
||||||
class User {
|
class User
|
||||||
private:
|
{
|
||||||
int _fd;
|
private:
|
||||||
|
short unsigned int _fd;
|
||||||
bool _registered;
|
bool _registered;
|
||||||
std::string _nickname;
|
std::string _nickname;
|
||||||
std::string _hostname;
|
std::string _hostname;
|
||||||
std::string _read_buffer;
|
std::string _read_buffer;
|
||||||
std::string _write_buffer;
|
std::string _write_buffer;
|
||||||
public:
|
std::string _username;
|
||||||
int getFd() const;
|
bool _hasNick;
|
||||||
|
bool _hasUser;
|
||||||
|
|
||||||
|
public:
|
||||||
|
User(short unsigned fd);
|
||||||
|
short unsigned int getFd() const;
|
||||||
bool isReadyToSend() const;
|
bool isReadyToSend() const;
|
||||||
bool isRegistered() const;
|
bool isRegistered() const;
|
||||||
std::string getNickname() const;
|
std::string getNickname() const;
|
||||||
|
|
@ -33,4 +37,6 @@ class User {
|
||||||
void appendToReadBuffer(const std::string &data);
|
void appendToReadBuffer(const std::string &data);
|
||||||
void appendToWriteBuffer(const std::string &data);
|
void appendToWriteBuffer(const std::string &data);
|
||||||
void setNickname(const std::string &nickname);
|
void setNickname(const std::string &nickname);
|
||||||
|
void setUsername(const std::string &username);
|
||||||
|
void checkRegistration();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,16 @@
|
||||||
|
|
||||||
PollManager::PollManager() {}
|
PollManager::PollManager() {}
|
||||||
|
|
||||||
PollManager::~PollManager() {
|
PollManager::~PollManager()
|
||||||
for (size_t i = 0; i < _fds.size(); ++i) {
|
{
|
||||||
|
for (size_t i = 0; i < _fds.size(); ++i)
|
||||||
|
{
|
||||||
close(_fds[i].fd);
|
close(_fds[i].fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollManager::pollLoop(int server_fd) {
|
void PollManager::pollLoop(int server_fd, std::vector<int> &newClients, std::vector<int> &disconnected, std::vector<std::pair<int, std::string> > &readyClients)
|
||||||
|
{
|
||||||
|
|
||||||
struct pollfd server_pollfd;
|
struct pollfd server_pollfd;
|
||||||
server_pollfd.fd = server_fd;
|
server_pollfd.fd = server_fd;
|
||||||
|
|
@ -25,57 +28,68 @@ void PollManager::pollLoop(int server_fd) {
|
||||||
|
|
||||||
std::cout << "Serveur prêt à accepter des connexions..." << std::endl;
|
std::cout << "Serveur prêt à accepter des connexions..." << std::endl;
|
||||||
|
|
||||||
while (true) {
|
// while (true) {
|
||||||
int poll_count = poll(&_fds[0], _fds.size(), -1);
|
int poll_count = poll(&_fds[0], _fds.size(), -1);
|
||||||
if (poll_count == -1) {
|
if (poll_count == -1)
|
||||||
std::cerr << "poll error\n" << std::endl;
|
{
|
||||||
continue;
|
std::cerr << "poll error\n"
|
||||||
|
<< std::endl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < _fds.size(); ++i) {
|
for (size_t i = 0; i < _fds.size(); ++i)
|
||||||
int fd = _fds[i].fd;
|
{
|
||||||
|
short unsigned fd = _fds[i].fd;
|
||||||
|
|
||||||
if ((fd == server_fd) && (_fds[i].revents & POLLIN)) {
|
if ((fd == server_fd) && (_fds[i].revents & POLLIN))
|
||||||
|
{
|
||||||
int client_fd = accept(server_fd, NULL, NULL);
|
int client_fd = accept(server_fd, NULL, NULL);
|
||||||
if (client_fd == -1) {
|
if (client_fd == -1)
|
||||||
|
{
|
||||||
std::cerr << "Error accept()" << std::endl;
|
std::cerr << "Error accept()" << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
addClient(client_fd);
|
addClient(client_fd);
|
||||||
|
newClients.push_back(client_fd);
|
||||||
}
|
}
|
||||||
else if (_fds[i].revents & POLLIN) {
|
else if (_fds[i].revents & POLLIN)
|
||||||
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
ssize_t bytes = recv(fd, buffer, sizeof(buffer) -1, 0);
|
ssize_t bytes = recv(fd, buffer, sizeof(buffer) - 1, 0);
|
||||||
if (bytes > 0) {
|
if (bytes > 0)
|
||||||
|
{
|
||||||
buffer[bytes] = '\0';
|
buffer[bytes] = '\0';
|
||||||
_buffers[fd] += buffer;
|
readyClients.push_back(std::make_pair(fd, std::string(buffer)));
|
||||||
std::cout << "Client " << fd << " send : " << buffer;
|
}
|
||||||
} else {
|
else
|
||||||
std::cout << "Client " << fd << " disconected." << std::endl;
|
{
|
||||||
// removeClient(fd);
|
removeClient(fd);
|
||||||
|
disconnected.push_back(fd);
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollManager::addClient(int fd) {
|
void PollManager::addClient(short unsigned fd)
|
||||||
|
{
|
||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
pfd.fd = fd;
|
pfd.fd = fd;
|
||||||
pfd.events = POLLIN;
|
pfd.events = POLLIN;
|
||||||
_fds.push_back(pfd);
|
_fds.push_back(pfd);
|
||||||
_buffers[fd] = "";
|
std::cout << "Client connected (fd " << fd << ")" << std::endl;
|
||||||
std::cout << "Client connecté (fd " << fd << ")" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollManager::removeClient(int fd) {
|
void PollManager::removeClient(short unsigned fd)
|
||||||
for (size_t i = 0; i < _fds.size(); ++i) {
|
{
|
||||||
if (_fds[i].fd == fd) {
|
for (size_t i = 0; i < _fds.size(); ++i)
|
||||||
|
{
|
||||||
|
if (_fds[i].fd == fd)
|
||||||
|
{
|
||||||
_fds.erase(_fds.begin() + i);
|
_fds.erase(_fds.begin() + i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_buffers.erase(fd);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
std::cout << "Client retiré (fd " << fd << ")" << std::endl;
|
std::cout << "Client disconnected (fd " << fd << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* Server.cpp :+: :+: :+: */
|
/* Server.cpp :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: sben-tay <sben-tay@student.42.fr> +#+ +:+ +#+ */
|
/* By: omoudni <omoudni@student.42paris.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/05/13 11:11:07 by rparodi #+# #+# */
|
/* Created: 2025/05/13 11:11:07 by rparodi #+# #+# */
|
||||||
/* Updated: 2025/05/21 13:03:51 by rparodi ### ########.fr */
|
/* Updated: 2025/05/21 21:50:03 by omoudni ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/******************************************************************************/
|
||||||
|
|
||||||
#include "color.hpp"
|
#include "color.hpp"
|
||||||
#include "server.hpp"
|
#include "server.hpp"
|
||||||
|
|
@ -37,6 +37,9 @@ Server::Server(int port, const std::string &password) : _port(port), _password(p
|
||||||
*/
|
*/
|
||||||
Server::~Server() {
|
Server::~Server() {
|
||||||
std::cout << CLR_GREY << "Info: Server destructor called" << CLR_RESET << std::endl;
|
std::cout << CLR_GREY << "Info: Server destructor called" << CLR_RESET << std::endl;
|
||||||
|
if (_serverFd != -1) {
|
||||||
|
close(_serverFd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -61,8 +64,47 @@ void Server::start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Serveur lancé sur le port " << _port << std::endl;
|
std::cout << "Serveur lancé sur le port " << _port << std::endl;
|
||||||
|
std::vector<int> newClients;
|
||||||
|
std::vector<int> disconnected;
|
||||||
|
std::vector<std::pair<int, std::string> > readyClients;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
newClients.clear();
|
||||||
|
disconnected.clear();
|
||||||
|
readyClients.clear();
|
||||||
|
_pollManager.pollLoop(_serverFd, newClients, disconnected, readyClients);
|
||||||
|
|
||||||
_pollManager.pollLoop(_serverFd);
|
// Handle new clients
|
||||||
|
for (size_t i = 0; i < newClients.size(); ++i)
|
||||||
|
_users[newClients[i]] = new User(newClients[i]);
|
||||||
|
// Handle disconnected clients
|
||||||
|
for (size_t i = 0; i < disconnected.size(); ++i)
|
||||||
|
{
|
||||||
|
delete _users[disconnected[i]];
|
||||||
|
_users.erase(disconnected[i]);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < readyClients.size(); ++i)
|
||||||
|
{
|
||||||
|
int fd = readyClients[i].first;
|
||||||
|
const std::string &data = readyClients[i].second;
|
||||||
|
if (_users.count(fd))
|
||||||
|
{
|
||||||
|
_users[fd]->appendToReadBuffer(data);
|
||||||
|
//print users
|
||||||
|
std::cout << "User " << fd << " is registered: " << _users[fd]->isRegistered() << std::endl;
|
||||||
|
std::cout << "Received data from fd " << fd << ": " << data << std::endl;
|
||||||
|
std::string cmd;
|
||||||
|
while (!(cmd = _users[fd]->extractFullCommand()).empty())
|
||||||
|
{
|
||||||
|
// This prints every command/message received from any client
|
||||||
|
std::cout << "Client " << fd << " says: " << cmd << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally: handle server shutdown, signals, etc.
|
||||||
|
}
|
||||||
close(_serverFd);
|
close(_serverFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
108
sources/core/user.cpp
Normal file
108
sources/core/user.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
/******************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* user.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: omoudni <omoudni@student.42paris.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/05/21 20:37:12 by omoudni #+# #+# */
|
||||||
|
/* Updated: 2025/05/21 21:44:58 by omoudni ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#include "core.hpp"
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
User::User(short unsigned int fd) : _fd(fd), _registered(false), _hasNick(false), _hasUser(false) {}
|
||||||
|
|
||||||
|
// Getter for fd
|
||||||
|
short unsigned int User::getFd() const
|
||||||
|
{
|
||||||
|
return _fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter for nickname
|
||||||
|
std::string User::getNickname() const
|
||||||
|
{
|
||||||
|
return _nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
void User::setUsername(const std::string &username)
|
||||||
|
{
|
||||||
|
_username = username;
|
||||||
|
_hasUser = true;
|
||||||
|
checkRegistration();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setter for nickname (with basic checks)
|
||||||
|
void User::setNickname(const std::string &nickname)
|
||||||
|
{
|
||||||
|
if (nickname.empty())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Nickname cannot be empty");
|
||||||
|
}
|
||||||
|
else if (nickname == "anonymous")
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("Nickname cannot be 'anonymous'");
|
||||||
|
}
|
||||||
|
else if (nickname.length() > 9)
|
||||||
|
{
|
||||||
|
throw std::length_error("Nickname is too long");
|
||||||
|
}
|
||||||
|
else if (nickname == _nickname)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("The nickname is the same");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_nickname = nickname;
|
||||||
|
_hasNick = true;
|
||||||
|
checkRegistration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registration state
|
||||||
|
bool User::isRegistered() const
|
||||||
|
{
|
||||||
|
return _registered;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append to read buffer
|
||||||
|
void User::appendToReadBuffer(const std::string &data)
|
||||||
|
{
|
||||||
|
_read_buffer += data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append to write buffer
|
||||||
|
void User::appendToWriteBuffer(const std::string &data)
|
||||||
|
{
|
||||||
|
_write_buffer += data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check registration
|
||||||
|
void User::checkRegistration()
|
||||||
|
{
|
||||||
|
if (!_registered && _hasNick && _hasUser)
|
||||||
|
{
|
||||||
|
_registered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the user is ready to send
|
||||||
|
bool User::isReadyToSend() const
|
||||||
|
{
|
||||||
|
return !_write_buffer.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract full command from read buffer
|
||||||
|
std::string User::extractFullCommand()
|
||||||
|
{
|
||||||
|
std::string command;
|
||||||
|
size_t pos = _read_buffer.find("\r\n");
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
command = _read_buffer.substr(0, pos);
|
||||||
|
_read_buffer.erase(0, pos + 2);
|
||||||
|
}
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* user.cpp :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/05/20 22:03:36 by rparodi #+# #+# */
|
|
||||||
/* Updated: 2025/05/20 22:15:14 by rparodi ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "user.hpp"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Getter for the fd of the user
|
|
||||||
*
|
|
||||||
* @return the actual fd of the user
|
|
||||||
*/
|
|
||||||
int User::getFd() const {
|
|
||||||
return this->_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Getter for the nickname of the user
|
|
||||||
*
|
|
||||||
* @return the actual nickname of the user
|
|
||||||
*/
|
|
||||||
std::string User::getNickname() const {
|
|
||||||
return this->_nickname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Setter for the nickname of the user (also checker)
|
|
||||||
*
|
|
||||||
* @param nickname the nickname given to set to the user
|
|
||||||
*/
|
|
||||||
void User::setNickname(const std::string &nickname) {
|
|
||||||
if (nickname.empty()) {
|
|
||||||
throw std::invalid_argument("Nickname cannot be empty");
|
|
||||||
} else if (nickname == "anonymous") {
|
|
||||||
throw std::invalid_argument("Nickname cannot be 'anonymous'");
|
|
||||||
} else if (nickname.length() > 9) {
|
|
||||||
throw std::length_error("Nickname is too long");
|
|
||||||
} else if (nickname == this->_nickname) {
|
|
||||||
throw std::invalid_argument("The nickname is the same");
|
|
||||||
} else {
|
|
||||||
this->_nickname = nickname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Getter for the state of the user
|
|
||||||
*
|
|
||||||
* @return true if the user is registered, false otherwise
|
|
||||||
*/
|
|
||||||
bool User::isRegistered() const {
|
|
||||||
return this->_registered;
|
|
||||||
}
|
|
||||||
void User::appendToReadBuffer(const std::string &data) {
|
|
||||||
std::cerr << CLR_RED << "Error: Method not found (" << __FILE_NAME__ ":" << __LINE__ << ")" << CLR_RESET << std::endl;
|
|
||||||
(void)data;
|
|
||||||
}
|
|
||||||
void User::appendToWriteBuffer(const std::string &data) {
|
|
||||||
std::cerr << CLR_RED << "Error: Method not found (" << __FILE_NAME__ ":" << __LINE__ << ")" << CLR_RESET << std::endl;
|
|
||||||
(void)data;
|
|
||||||
}
|
|
||||||
std::string User::extractFullCommand() {
|
|
||||||
std::cerr << CLR_RED << "Error: Method not found (" << __FILE_NAME__ ":" << __LINE__ << ")" << CLR_RESET << std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool User::isReadyToSend() const {
|
|
||||||
std::cerr << CLR_RED << "Error: Method not found (" << __FILE_NAME__ ":" << __LINE__ << ")" << CLR_RESET << std::endl;
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue