Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ////////////////////client.h//////////////////////
- #ifndef CLIENT_H
- #define CLIENT_H
- #include <string>
- #include <QTcpSocket>
- namespace Irc
- {
- class Client;
- class User;
- } //namespace Irc
- #include <boost/shared_ptr.hpp>
- #include <vector>
- #include "auxiliar.h"
- class Irc::Client : public QObject
- {
- Q_OBJECT
- public:
- Client(boost::shared_ptr<QTcpSocket> _sock, QObject* parent = 0);
- ~Client();
- static int clientCount;
- void send(const std::string& msg);
- void close();
- std::string getIP() const;
- std::string getHostName() const;
- public slots:
- void recv();
- void disconnectClient();
- void newError(QAbstractSocket::SocketError err);
- signals:
- void newUser(Irc::User* user);
- private:
- QTcpSocket* m_socket;
- Irc::User* m_user;
- bool sentMotd;
- void firstTime();
- void handleRequest(StringVec __msg);
- void sendLine(const char *fmt, ...);
- };
- #endif
- ///////////////client.cpp///////////////////
- #include "client.h"
- #include <iostream>
- #include <boost/shared_ptr.hpp>
- #include <QtNetwork>
- #include <sstream>
- #include "user.h"
- #include "channels.h"
- #include "auxiliar.h"
- #include "defines.h"
- #include "configreader.h"
- #include <cstdarg>
- #include <cstdio>
- extern Irc::Config* g_config;
- extern Channels* g_channels;
- int Irc::Client::clientCount;
- Irc::Client::Client(boost::shared_ptr<QTcpSocket> _sock, QObject* parent)
- : QObject(parent), m_socket(_sock.get())
- {
- clientCount++;
- sentMotd = false;
- tcout() << "New Client." << std::endl;
- connect(m_socket, SIGNAL(readyRead()),
- this, SLOT(recv()));
- connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
- this, SLOT(newError(QAbstractSocket::SocketError)));
- connect(m_socket, SIGNAL(disconnected()),
- this, SLOT(disconnectClient()));
- firstTime();
- }
- void Irc::Client::sendLine(const char *fmt, ...)
- {
- va_list arg;
- va_start(arg, fmt);
- char buffer[512];
- vsprintf(buffer, fmt, arg);
- va_end(arg);
- send(std::string(buffer));
- }
- void Irc::Client::firstTime()
- {
- std::stringstream ss;
- ss << MOTD_COMMON << "Looking up your hostname\r\n";
- send(ss.str());
- ss.str("");
- ss << MOTD_COMMON << "Checking Ident\r\n";
- send(ss.str());
- ss.str("");
- if (!getHostName().empty())
- ss << MOTD_COMMON << "Found your hostname";
- else
- ss << MOTD_COMMON << "Couldn't look up your hostname";
- ss << "\r\n";
- send(ss.str());
- ss.str("");
- switch (ident(getIP())) {
- case SOCKET_NOT_INITED:
- {
- tcout() << "[Info - Client::useIdent] - Unable to initalize socket." << std::endl;
- break;
- }
- case SOCKET_NOT_CONNECTED:
- {
- tcout() << "[Info - Client::useIdent] - Unable to connect socket." << std::endl;
- break;
- }
- case SOCKET_UNABLE_TO_WRITE:
- {
- tcout() << "[Info - Client::useIdent] - Unable to write data on the socket." << std::endl;
- break;
- }
- case SOCKET_UNABLE_TO_READ:
- {
- tcout() << "[Info - Client::useIdent] - Unable to read data on the socket." << std::endl;
- break;
- }
- case CONNECTION_SUCCESS:
- default:
- {
- ss << MOTD_COMMON << "Got ident response";
- ss << "\r\n";
- send(ss.str());
- return;
- }
- }
- ss.str("");
- ss << MOTD_COMMON << "No ident response";
- ss << "\r\n";
- send(ss.str());
- }
- Irc::Client::~Client()
- {
- delete m_socket;
- clientCount--;
- }
- void Irc::Client::send(const std::string& msg)
- {
- m_socket->write(msg.c_str());
- }
- void Irc::Client::recv()
- {
- if (!m_socket)
- return;
- char buffer[512];
- while (m_socket->canReadLine()) {
- m_socket->readLine(buffer, 512);
- std::string str = std::string(buffer);
- if (str.rfind("\r\n") == std::string::npos)
- continue;
- str.erase(str.rfind("\r\n"));
- tcout() << "Received message from client: " << getHostName() << " :" << str << std::endl;
- StringVec splited = splitString(str, " ");
- if (splited[0] == "USER") {
- if (splited.size() < 4)
- continue;
- if (!m_user) {
- if (splited[1].length() >= 15)
- m_user = new User(splited[1].substr(0, 15), this);
- else
- m_user = new User(splited[1], this);
- } else {
- if (splited[1].length() >= 15)
- m_user->setName(splited[1].substr(0, 15));
- else
- m_user->setName(splited[1]);
- }
- tcout() << "New user with name: " << m_user->getName() << std::endl;
- } else if (splited[0] == "NICK") {
- if (splited.size() < 2)
- continue;
- if (!m_user) {
- if (splited.size() >= 15)
- m_user = new Irc::User(splited[1].substr(0, 15), this);
- else
- m_user = new Irc::User(splited[1], this);
- }
- if (splited.size() >= 15)
- m_user->setNick(splited[1].substr(0, 15));
- else
- m_user->setNick(splited[1]);
- if (!sentMotd) {
- m_user->sendMotd(":%s 001 %s :Welcome to %s network, %s\r\n", m_user->getServer().c_str(),
- m_user->getName().c_str(), g_config->getString(0x07).c_str(), m_user->getNick().c_str());
- m_user->sendMotd(":%s 002 %s :Your host is %s running version %s\r\n", m_user->getServer().c_str(),
- m_user->getName().c_str(), m_user->getHost().c_str(), __DISTURBTION__);
- m_user->sendMotd(":%s 003 %s :This server was created %s\r\n", m_user->getServer().c_str(),
- m_user->getName().c_str(), __DATE__);
- m_user->sendMotd(":%s 252 %s %d :operator(s) online\r\n", m_user->getServer().c_str(),
- m_user->getName().c_str(), m_user->operCount);
- m_user->sendMotd(":%s NOTICE %s :Highest connection count: %d (%d clients)\r\n", m_user->getServer().c_str(),
- m_user->getName().c_str(), m_user->userCount, Irc::Client::clientCount);
- sentMotd = true;
- }
- emit newUser(m_user);
- tcout() << "New user with nick: " << m_user->getNick() << std::endl;
- } else {
- handleRequest(splited);
- }
- }
- }
- void Irc::Client::disconnectClient()
- {
- Irc::tcout() << "Client disconnected: " << m_socket->peerAddress().toString().toStdString() << std::endl;
- m_socket->deleteLater();
- clientCount--;
- delete m_user;
- }
- void Irc::Client::newError(QAbstractSocket::SocketError err)
- {
- switch (err) {
- case QAbstractSocket::ConnectionRefusedError:
- {
- sendLine("ERROR :Closing Link %s (Connection refused).\r\n", getIP().c_str());
- tcout() << "Closing link " << getIP() << " (Connection refused)" << std::endl;
- break;
- }
- case QAbstractSocket::RemoteHostClosedError:
- {
- sendLine("ERROR :Closing Link %s (Remote host closed connection).\r\n", getIP().c_str());
- tcout() << "Closing link " << getIP() << " (Remote host closed connection)" << std::endl;
- break;
- }
- case QAbstractSocket::SocketTimeoutError:
- {
- sendLine("ERROR :Closing Link %s (Ping timeout).\r\n", getIP().c_str());
- tcout() << "Closing link " << getIP() << " (Ping timeout)" << std::endl;
- break;
- }
- default:
- {
- sendLine("ERROR :Closing Link %s (%s).\r\n", getIP().c_str(), m_socket->errorString().toStdString().c_str());
- tcout() << "Closing link " << getIP() << " (" << m_socket->errorString().toStdString() << ")" << std::endl;
- break;
- }
- }
- m_socket->disconnectFromHost();
- }
- std::string Irc::Client::getIP() const
- {
- return m_socket->peerAddress().toString().toStdString();
- }
- std::string Irc::Client::getHostName() const
- {
- if (m_socket->peerAddress().isNull())
- return std::string();
- return m_socket->peerAddress().toString().toStdString();
- }
- void Irc::Client::handleRequest(StringVec __msg)
- {
- StringVec splited = __msg;
- if (splited[0] == "MODE") {
- if (!m_user->getName().empty() && !m_user->getNick().empty()) {
- if (splited[1] != m_user->getNick()) { //channel mode
- if (splited[1].substr(0, 1) == "#") {
- Channel* chan = m_user->getChannelByName(splited[1]);
- if (!chan) {
- m_user->sendLine(":%s 442 %s %s :You're not on that channel\r\n", m_user->getServer().c_str(),
- m_user->getName().c_str(), splited[1].c_str());
- return;
- } else {
- if (chan->getUserMode(m_user, Irc::UM_OP)) {
- for (_UsersMap::iterator it = chan->getUsers().begin(); it != chan->getUsers().end(); ++it)
- it->second->sendLine(":%s!%s@%s MODE %s %s\r\n", m_user->getNick().c_str(),
- m_user->getIdent().c_str(), m_user->getHost().c_str(), splited[1].c_str(),
- splited[2].c_str());
- } else {
- m_user->sendLine(":%s 482 %s %s :You're not channel operator\r\n", m_user->getServer().c_str(),
- m_user->getName().c_str(), splited[1].c_str());
- return;
- }
- }
- }
- } else { //user mode
- if (m_user->hasMode(*const_cast<char*>(splited[2].c_str())))
- return;
- m_user->setMode(*const_cast<char*>(splited[2].c_str()));
- m_user->sendLine(":%s!%s@%s MODE %s %s\r\n", m_user->getNick().c_str(),
- m_user->getIdent().c_str(), m_user->getHost().c_str(), m_user->getNick().c_str(),
- splited[2].c_str());
- }
- }
- } else if (splited[0] == "JOIN") {
- if (!m_user->getName().empty() && !m_user->getNick().empty()) {
- if (splited.size() >= 1) {
- Channel* p = g_channels->getChannel(splited[1]);
- if (!p) { //create new
- Channel* chan = new Channel(splited[1]);
- m_user->sendLine(":%s 353 %s = %s %s\r\n", m_user->getServer().c_str(),
- m_user->getNick().c_str(), chan->getName().c_str(), m_user->getNick().c_str());
- m_user->sendLine(":%s 366 %s %s :End of /NAMES list.\r\n", m_user->getServer().c_str(),
- m_user->getNick().c_str(), chan->getName().c_str());
- g_channels->addChannel(chan);
- } else { //already exists
- Ban *b = p->getBan(m_user);
- if (!b) { //b& or not
- if (!p->addUser(m_user))
- return;
- std::string users = "";
- for (_UsersMap::const_iterator it = p->getUsers().begin(); it != p->getUsers().end(); ++it) {
- if (!it->second)
- continue;
- users += it->second->getNick() + " ";
- }
- m_user->sendLine(":%s 353 %s = %s %s\r\n", m_user->getServer().c_str(),
- m_user->getNick().c_str(), p->getName().c_str(), users.c_str());
- m_user->sendLine(":%s 366 %s %s :End of /NAMES list.\r\n", m_user->getServer().c_str(),
- m_user->getNick().c_str(), p->getName().c_str());
- } else {
- m_user->sendLine(":%s 474 %s %s :Cannot join channel, you are banned (+b)\r\n",
- m_user->getServer().c_str(), m_user->getNick().c_str(), splited[1].c_str());
- return;
- }
- }
- }
- }
- }
- }
- void Irc::Client::close()
- {
- m_socket->disconnectFromHost();
- m_socket->close();
- clientCount--;
- delete m_user;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement