Advertisement
Guest User

Untitled

a guest
Nov 27th, 2010
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.27 KB | None | 0 0
  1. ////////////////////client.h//////////////////////
  2. #ifndef CLIENT_H
  3. #define CLIENT_H
  4.  
  5. #include <string>
  6.  
  7. #include <QTcpSocket>
  8.  
  9. namespace Irc
  10. {
  11.     class Client;
  12.     class User;
  13. } //namespace Irc
  14. #include <boost/shared_ptr.hpp>
  15. #include <vector>
  16.  
  17. #include "auxiliar.h"
  18.  
  19. class Irc::Client : public QObject
  20. {
  21.     Q_OBJECT
  22.     public:
  23.         Client(boost::shared_ptr<QTcpSocket> _sock, QObject* parent = 0);
  24.         ~Client();
  25.  
  26.         static int clientCount;
  27.  
  28.         void send(const std::string& msg);
  29.         void close();
  30.  
  31.         std::string getIP() const;
  32.         std::string getHostName() const;
  33.  
  34.     public slots:
  35.         void recv();
  36.         void disconnectClient();
  37.         void newError(QAbstractSocket::SocketError err);
  38.  
  39.     signals:
  40.         void newUser(Irc::User* user);
  41.  
  42.     private:
  43.         QTcpSocket* m_socket;
  44.         Irc::User* m_user;
  45.         bool sentMotd;
  46.         void firstTime();
  47.         void handleRequest(StringVec __msg);
  48.         void sendLine(const char *fmt, ...);
  49. };
  50. #endif
  51. ///////////////client.cpp///////////////////
  52. #include "client.h"
  53.  
  54. #include <iostream>
  55. #include <boost/shared_ptr.hpp>
  56. #include <QtNetwork>
  57. #include <sstream>
  58.  
  59. #include "user.h"
  60. #include "channels.h"
  61. #include "auxiliar.h"
  62. #include "defines.h"
  63. #include "configreader.h"
  64.  
  65. #include <cstdarg>
  66. #include <cstdio>
  67.  
  68. extern Irc::Config* g_config;
  69. extern Channels* g_channels;
  70.  
  71. int Irc::Client::clientCount;
  72.  
  73. Irc::Client::Client(boost::shared_ptr<QTcpSocket> _sock, QObject* parent)
  74.     : QObject(parent), m_socket(_sock.get())
  75. {
  76.     clientCount++;
  77.     sentMotd = false;
  78.     tcout() << "New Client." << std::endl;
  79.     connect(m_socket, SIGNAL(readyRead()),
  80.         this, SLOT(recv()));
  81.     connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
  82.         this, SLOT(newError(QAbstractSocket::SocketError)));
  83.     connect(m_socket, SIGNAL(disconnected()),
  84.         this, SLOT(disconnectClient()));
  85.     firstTime();
  86. }
  87.  
  88. void Irc::Client::sendLine(const char *fmt, ...)
  89. {
  90.     va_list arg;
  91.     va_start(arg, fmt);
  92.     char buffer[512];
  93.     vsprintf(buffer, fmt, arg);
  94.     va_end(arg);
  95.     send(std::string(buffer));
  96. }
  97.  
  98. void Irc::Client::firstTime()
  99. {
  100.     std::stringstream ss;
  101.     ss << MOTD_COMMON << "Looking up your hostname\r\n";
  102.     send(ss.str());
  103.     ss.str("");
  104.     ss << MOTD_COMMON << "Checking Ident\r\n";
  105.     send(ss.str());
  106.     ss.str("");
  107.     if (!getHostName().empty())
  108.         ss << MOTD_COMMON << "Found your hostname";
  109.     else
  110.         ss << MOTD_COMMON << "Couldn't look up your hostname";
  111.  
  112.     ss << "\r\n";
  113.     send(ss.str());
  114.     ss.str("");
  115.     switch (ident(getIP())) {
  116.         case SOCKET_NOT_INITED:
  117.         {
  118.             tcout() << "[Info - Client::useIdent] - Unable to initalize socket." << std::endl;
  119.             break;
  120.         }
  121.         case SOCKET_NOT_CONNECTED:
  122.         {
  123.             tcout() << "[Info - Client::useIdent] - Unable to connect socket." << std::endl;
  124.             break;
  125.         }
  126.         case SOCKET_UNABLE_TO_WRITE:
  127.         {
  128.             tcout() << "[Info - Client::useIdent] - Unable to write data on the socket." << std::endl;
  129.             break;
  130.         }
  131.         case SOCKET_UNABLE_TO_READ:
  132.         {
  133.             tcout() << "[Info - Client::useIdent] - Unable to read data on the socket." << std::endl;
  134.             break;
  135.         }
  136.         case CONNECTION_SUCCESS:
  137.         default:
  138.         {
  139.             ss << MOTD_COMMON << "Got ident response";
  140.             ss << "\r\n";
  141.             send(ss.str());
  142.             return;
  143.         }
  144.     }
  145.     ss.str("");
  146.     ss << MOTD_COMMON << "No ident response";
  147.     ss << "\r\n";
  148.     send(ss.str());
  149. }
  150.  
  151. Irc::Client::~Client()
  152. {
  153.     delete m_socket;
  154.     clientCount--;
  155. }
  156.  
  157. void Irc::Client::send(const std::string& msg)
  158. {
  159.     m_socket->write(msg.c_str());
  160. }
  161.  
  162. void Irc::Client::recv()
  163. {
  164.     if (!m_socket)
  165.         return;
  166.  
  167.     char buffer[512];
  168.     while (m_socket->canReadLine()) {
  169.         m_socket->readLine(buffer, 512);
  170.         std::string str = std::string(buffer);
  171.         if (str.rfind("\r\n") == std::string::npos)
  172.             continue;
  173.  
  174.         str.erase(str.rfind("\r\n"));
  175.         tcout() << "Received message from client: " << getHostName() << " :" << str << std::endl;
  176.         StringVec splited = splitString(str, " ");
  177.         if (splited[0] == "USER") {
  178.             if (splited.size() < 4)
  179.                 continue;
  180.  
  181.             if (!m_user) {
  182.                 if (splited[1].length() >= 15)
  183.                     m_user = new User(splited[1].substr(0, 15), this);
  184.                 else
  185.                     m_user = new User(splited[1], this);
  186.             } else {
  187.                 if (splited[1].length() >= 15)
  188.                     m_user->setName(splited[1].substr(0, 15));
  189.                 else
  190.                     m_user->setName(splited[1]);
  191.             }
  192.             tcout() << "New user with name: " << m_user->getName() << std::endl;
  193.         } else if (splited[0] == "NICK") {
  194.             if (splited.size() < 2)
  195.                 continue;
  196.  
  197.             if (!m_user) {
  198.                 if (splited.size() >= 15)
  199.                     m_user = new Irc::User(splited[1].substr(0, 15), this);
  200.                 else
  201.                     m_user = new Irc::User(splited[1], this);
  202.             }
  203.  
  204.             if (splited.size() >= 15)
  205.                 m_user->setNick(splited[1].substr(0, 15));
  206.             else
  207.                 m_user->setNick(splited[1]);
  208.  
  209.             if (!sentMotd) {
  210.                 m_user->sendMotd(":%s 001 %s :Welcome to %s network, %s\r\n", m_user->getServer().c_str(),
  211.                     m_user->getName().c_str(), g_config->getString(0x07).c_str(), m_user->getNick().c_str());
  212.                 m_user->sendMotd(":%s 002 %s :Your host is %s running version %s\r\n", m_user->getServer().c_str(),
  213.                     m_user->getName().c_str(), m_user->getHost().c_str(), __DISTURBTION__);
  214.                 m_user->sendMotd(":%s 003 %s :This server was created %s\r\n", m_user->getServer().c_str(),
  215.                     m_user->getName().c_str(), __DATE__);
  216.                 m_user->sendMotd(":%s 252 %s %d :operator(s) online\r\n", m_user->getServer().c_str(),
  217.                     m_user->getName().c_str(), m_user->operCount);
  218.                 m_user->sendMotd(":%s NOTICE %s :Highest connection count: %d (%d clients)\r\n", m_user->getServer().c_str(),
  219.                     m_user->getName().c_str(), m_user->userCount, Irc::Client::clientCount);
  220.                 sentMotd = true;
  221.             }
  222.             emit newUser(m_user);
  223.             tcout() << "New user with nick: " << m_user->getNick() << std::endl;
  224.         } else {
  225.             handleRequest(splited);
  226.         }
  227.     }
  228. }
  229.  
  230. void Irc::Client::disconnectClient()
  231. {
  232.     Irc::tcout() << "Client disconnected: " << m_socket->peerAddress().toString().toStdString() << std::endl;
  233.     m_socket->deleteLater();
  234.     clientCount--;
  235.     delete m_user;
  236. }
  237.  
  238. void Irc::Client::newError(QAbstractSocket::SocketError err)
  239. {
  240.     switch (err) {
  241.         case QAbstractSocket::ConnectionRefusedError:
  242.         {
  243.             sendLine("ERROR :Closing Link %s (Connection refused).\r\n", getIP().c_str());
  244.             tcout() << "Closing link " << getIP() << " (Connection refused)" << std::endl;
  245.             break;
  246.         }
  247.         case QAbstractSocket::RemoteHostClosedError:
  248.         {
  249.             sendLine("ERROR :Closing Link %s (Remote host closed connection).\r\n", getIP().c_str());
  250.             tcout() << "Closing link " << getIP() << " (Remote host closed connection)" << std::endl;
  251.             break;
  252.         }
  253.         case QAbstractSocket::SocketTimeoutError:
  254.         {
  255.             sendLine("ERROR :Closing Link %s (Ping timeout).\r\n", getIP().c_str());
  256.             tcout() << "Closing link " << getIP() << " (Ping timeout)" << std::endl;
  257.             break;
  258.         }
  259.         default:
  260.         {
  261.             sendLine("ERROR :Closing Link %s (%s).\r\n", getIP().c_str(), m_socket->errorString().toStdString().c_str());
  262.             tcout() << "Closing link " << getIP() << " (" << m_socket->errorString().toStdString() << ")" << std::endl;
  263.             break;
  264.         }
  265.     }
  266.     m_socket->disconnectFromHost();
  267. }
  268.  
  269. std::string Irc::Client::getIP() const
  270. {
  271.     return m_socket->peerAddress().toString().toStdString();
  272. }
  273.  
  274. std::string Irc::Client::getHostName() const
  275. {
  276.     if (m_socket->peerAddress().isNull())
  277.         return std::string();
  278.  
  279.     return m_socket->peerAddress().toString().toStdString();
  280. }
  281.  
  282. void Irc::Client::handleRequest(StringVec __msg)
  283. {
  284.     StringVec splited = __msg;
  285.     if (splited[0] == "MODE") {
  286.         if (!m_user->getName().empty() && !m_user->getNick().empty()) {
  287.             if (splited[1] != m_user->getNick()) { //channel mode
  288.                 if (splited[1].substr(0, 1) == "#") {
  289.                     Channel* chan = m_user->getChannelByName(splited[1]);
  290.                     if (!chan) {
  291.                         m_user->sendLine(":%s 442 %s %s :You're not on that channel\r\n", m_user->getServer().c_str(),
  292.                             m_user->getName().c_str(), splited[1].c_str());
  293.                         return;
  294.                     } else {
  295.                         if (chan->getUserMode(m_user, Irc::UM_OP)) {
  296.                             for (_UsersMap::iterator it = chan->getUsers().begin(); it != chan->getUsers().end(); ++it)
  297.                                 it->second->sendLine(":%s!%s@%s MODE %s %s\r\n", m_user->getNick().c_str(),
  298.                                     m_user->getIdent().c_str(), m_user->getHost().c_str(), splited[1].c_str(),
  299.                                         splited[2].c_str());
  300.                         } else {
  301.                             m_user->sendLine(":%s 482 %s %s :You're not channel operator\r\n", m_user->getServer().c_str(),
  302.                                 m_user->getName().c_str(), splited[1].c_str());
  303.                             return;
  304.                         }
  305.                     }
  306.                 }
  307.             } else { //user mode
  308.                 if (m_user->hasMode(*const_cast<char*>(splited[2].c_str())))
  309.                     return;
  310.  
  311.                 m_user->setMode(*const_cast<char*>(splited[2].c_str()));
  312.                 m_user->sendLine(":%s!%s@%s MODE %s %s\r\n", m_user->getNick().c_str(),
  313.                     m_user->getIdent().c_str(), m_user->getHost().c_str(), m_user->getNick().c_str(),
  314.                         splited[2].c_str());
  315.             }
  316.         }
  317.     } else if (splited[0] == "JOIN") {
  318.         if (!m_user->getName().empty() && !m_user->getNick().empty()) {
  319.             if (splited.size() >= 1) {
  320.                 Channel* p = g_channels->getChannel(splited[1]);
  321.                 if (!p) { //create new
  322.                     Channel* chan = new Channel(splited[1]);
  323.                     m_user->sendLine(":%s 353 %s = %s %s\r\n", m_user->getServer().c_str(),
  324.                         m_user->getNick().c_str(), chan->getName().c_str(), m_user->getNick().c_str());
  325.                     m_user->sendLine(":%s 366 %s %s :End of /NAMES list.\r\n", m_user->getServer().c_str(),
  326.                         m_user->getNick().c_str(), chan->getName().c_str());
  327.                     g_channels->addChannel(chan);
  328.                 } else { //already exists
  329.                     Ban *b = p->getBan(m_user);
  330.                     if (!b) { //b& or not
  331.                         if (!p->addUser(m_user))
  332.                             return;
  333.  
  334.                         std::string users = "";
  335.                         for (_UsersMap::const_iterator it = p->getUsers().begin(); it != p->getUsers().end(); ++it) {
  336.                             if (!it->second)
  337.                                 continue;
  338.  
  339.                             users += it->second->getNick() + " ";
  340.                         }
  341.                         m_user->sendLine(":%s 353 %s = %s %s\r\n", m_user->getServer().c_str(),
  342.                             m_user->getNick().c_str(), p->getName().c_str(), users.c_str());
  343.                         m_user->sendLine(":%s 366 %s %s :End of /NAMES list.\r\n", m_user->getServer().c_str(),
  344.                             m_user->getNick().c_str(), p->getName().c_str());
  345.                     } else {
  346.                         m_user->sendLine(":%s 474 %s %s :Cannot join channel, you are banned (+b)\r\n",
  347.                             m_user->getServer().c_str(), m_user->getNick().c_str(), splited[1].c_str());
  348.                         return;
  349.                     }
  350.                 }
  351.             }
  352.         }
  353.     }
  354. }
  355.  
  356. void Irc::Client::close()
  357. {
  358.     m_socket->disconnectFromHost();
  359.     m_socket->close();
  360.     clientCount--;
  361.     delete m_user;
  362. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement