Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ********************************************************************************************
- //Socket initialization, connection (send) , thread pour receive , send pour envoyer une commande, typedef (function pointer)
- #ifndef Connection_h__
- #define Connection_h__
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include "IncWindow.h"
- #include "UserCommand.h"
- class Server;
- #pragma comment(lib, "ws2_32.lib")
- enum ConnectionState
- {
- CS_STARTED=0,
- CS_ERROR_STARTING,
- CS_ERROR_SENDING,
- CS_ERROR_RECEIVING,
- CS_ERROR_CLOSING,
- CS_CLOSED,
- };
- class Connection
- {
- public :
- static ConnectionState Begin(Server& serv);
- static ConnectionState Close();
- static void SendUserCommand(UserCommand cmd);
- private :
- static DWORD WINAPI Run(LPVOID lpParam);
- private :
- static WSADATA mWSAData;
- static SOCKET mSock;
- static SOCKADDR_IN mSin;
- static HANDLE mRecvThread;
- static bool mRunning;
- };
- #endif // Connexion_h__
- ********************************************************************************************
- #include "Connection.h"
- #include "IRCSession.h"
- #include "Server.h"
- #include "ServerCommand.h"
- #include <memory>
- WSADATA Connection::mWSAData;
- SOCKET Connection::mSock;
- SOCKADDR_IN Connection::mSin;
- HANDLE Connection::mRecvThread;
- bool Connection::mRunning = false;
- ConnectionState Connection::Begin(Server& serv)
- {
- WSAStartup(MAKEWORD(2,0), &mWSAData);
- hostent* remotHost = gethostbyname(serv.GetHost().c_str());
- if(remotHost == NULL) return CS_ERROR_STARTING;
- in_addr addr;
- addr.s_addr = *(u_long *)remotHost->h_addr_list[0];
- mSin.sin_addr.s_addr = addr.s_addr;
- mSin.sin_family = AF_INET;
- mSin.sin_port = htons(u_short(serv.GetPort()));
- mSock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
- if(mSock == INVALID_SOCKET)
- {
- return CS_ERROR_STARTING;
- }
- if(connect(mSock,(SOCKADDR*)&mSin,sizeof(mSin)) == SOCKET_ERROR)
- {
- printf("Error in connection : %d",WSAGetLastError());
- return CS_ERROR_STARTING;
- }
- mRunning = true;
- mRecvThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Connection::Run,0,0,NULL);
- if(mRecvThread == NULL)
- {
- return CS_ERROR_STARTING;
- }
- return CS_STARTED;
- }
- ConnectionState Connection::Close()
- {
- mRunning = false;
- if(mSock)
- {
- if(shutdown(mSock, SD_BOTH)) return CS_ERROR_CLOSING;
- if(closesocket(mSock)) return CS_ERROR_CLOSING;
- }
- WSACleanup();
- if(!CloseHandle(mRecvThread)) return CS_ERROR_CLOSING;
- return CS_CLOSED;
- }
- void Connection::SendUserCommand(UserCommand cmd)
- {
- char buffer[1024];
- size_t dataLenght = cmd.ToString().length();
- memcpy(buffer,cmd.ToString().c_str(),dataLenght);
- buffer[dataLenght] = 0x0D;
- buffer[dataLenght + 1] = 0x0A;
- int result = send(mSock,buffer,dataLenght + 2,0);
- if(result == SOCKET_ERROR)
- {
- Close();
- }
- }
- DWORD WINAPI Connection::Run(LPVOID lpParam)
- {
- char buffer[4096];
- //Main receive loop
- while(mRunning)
- {
- int rec = recv(mSock,buffer,sizeof(buffer),0);
- if(rec > 0)
- {
- unsigned int i = 0;
- unsigned int crlfOffset=0;
- while( i < rec - 1)
- {
- if(buffer[i] == 0xD && buffer[i+1] == 0x0A)
- {
- buffer[i++]='\0';
- buffer[i] = '\0';
- ServerCommand serv;
- serv.Parse(buffer + crlfOffset);
- IRCSession::OnReceiveCommand(serv);
- crlfOffset = i+1;
- }
- i++;
- }
- }
- Sleep(100);
- }
- return 0;
- }
- ********************************************************************************************
- #ifndef Event_h__
- #define Event_h__
- #include "EventType.h"
- struct Event
- {
- public:
- Event(EventType type = EVT_MAX) : mType(type){}
- virtual ~Event() {};
- private:
- public:
- EventType mType;
- };
- #endif // Event_h__
- ********************************************************************************************
- #ifndef EventPing_h__
- #define EventPing_h__
- #include "Event.h"
- #include "Ping.h"
- struct EventPing : Event
- {
- public :
- EventPing(Ping p) : Event(EVT_RCV_PING) , mPing(p){}
- EventPing(string serverCode): Event(EVT_RCV_PING){mPing.mServerCode = serverCode;}
- virtual ~EventPing(){}
- public:
- Ping mPing;
- };
- #endif // EventPing_h__
- ********************************************************************************************
- #ifndef EventStartSession_h__
- #define EventStartSession_h__
- #include "Event.h"
- class User;
- class Server;
- struct EventStartSession : Event
- {
- public:
- EventStartSession(User user , Server serv) : Event(EVT_START_SESSION), mUser(user), mServer(serv) {}
- virtual ~EventStartSession() {}
- public:
- User mUser;
- Server mServer;
- };
- #endif // EventStartSession_h__
- ********************************************************************************************
- #ifndef EventType_h__
- #define EventType_h__
- enum EventType
- {
- EVT_START_SESSION=0,
- EVT_RCV_PING,
- EVT_RCV_PRIVMSG,
- EVT_MAX,
- };
- #endif // EventType_h__
- ********************************************************************************************
- #ifndef FastNumeric_h__
- #define FastNumeric_h__
- #include <cctype>
- #include <string>
- inline bool isNumeric(const char* val)
- {
- if(strlen(val) < 1)
- {
- return false;
- }
- bool result = true;
- for(char* p = (char*)val; *p ; p++){result += (bool)(isdigit(*p));}
- return result;
- }
- #endif // FastNumeric_h__
- ********************************************************************************************
- #ifndef FastString_h__
- #define FastString_h__
- #include "SafeDelete.h"
- #include <string>
- //fast string manipulations
- unsigned int GetWordCount(const char* s)
- {
- unsigned int i =0;
- unsigned int result=0;
- while(i < strlen(s))
- {
- if(s[i] == ' ')
- {
- result++;
- }
- i++;
- }
- return result + 1;
- }
- unsigned int GetWordOffset(const char* s,unsigned int position)
- {
- unsigned int offset = 0;
- unsigned int i =0;
- bool found = false;
- while(i < strlen(s) && !found && position >= 1)
- {
- if(s[i] == ' ')
- {
- if(position == 0)
- {
- found = true;
- }
- position--;
- }
- offset++;
- i++;
- }
- return offset;
- }
- unsigned int GetWordLenght(const char* s,unsigned int position)
- {
- unsigned int offset = GetWordOffset(s,position);
- unsigned int i =0;
- while((offset +i) < strlen(s) && s[offset+i] != ' ')
- {
- i++;
- }
- return i;
- }
- char** GetWords(const char* s)
- {
- unsigned int wordCount = GetWordCount(s);
- char** result = new char*[wordCount];
- for(unsigned int i=0 ; i < wordCount ; i++)
- {
- unsigned int lenght = GetWordLenght(s,i);
- result[i] = new char[lenght+1];
- const char* word = (s+GetWordOffset(s,i));
- memcpy(result[i],word,lenght);
- result[i][lenght]= '\0';
- }
- return result;
- }
- void DeleteWords(char** words,unsigned int count)
- {
- SAFE_DELETE_ARRAY_2D(words,count);
- }
- #endif // FastString_h__
- ********************************************************************************************
- #ifndef Queue_h__
- #define Queue_h__
- #include <queue>
- using namespace std;
- #endif // Queue_h__
- ********************************************************************************************
- #ifndef Session_h__
- #define Session_h__
- #include "IncWindow.h"
- #include "IncQueue.h"
- #include "SharedPointer.h"
- class ServerCommand;
- class Server;
- class User;
- struct Event;
- typedef void (*PtrReceiveMessage)(const char* message);
- class IRCSession
- {
- public :
- static void OnReceiveCommand(ServerCommand cmd);
- static void HandleChatBoxMssg(const char* msg);
- static void SetReceiveMessageFunction(PtrReceiveMessage fct);
- static void HandleEvent(SharedPointer<Event> evt);
- private :
- static DWORD WINAPI Run(LPVOID lpParam);
- private :
- static Server mServer;
- static User mUser;
- static PtrReceiveMessage mRcvMsgFct;
- static HANDLE mRunThread;
- static bool mRunning;
- static CRITICAL_SECTION mSection;
- static queue<SharedPointer<Event>> mEventQueue;
- };
- #endif // Session_h__
- ********************************************************************************************
- #ifndef IncString_h__
- #define IncString_h__
- #include <string>
- using namespace std;
- #endif // IncString_h__
- ********************************************************************************************
- #ifndef IncVector_h__
- #define IncVector_h__
- #include <vector>
- using namespace std;
- #endif // IncVector_h__
- ********************************************************************************************
- #ifndef IncWindow_h__
- #define IncWindow_h__
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #endif
- #endif // IncWindow_h__
- ********************************************************************************************
- #include "IRCSession.h"
- #include "FastString.h"
- #include "Connection.h"
- #include "ServerCommand.h"
- #include "Server.h"
- #include "User.h"
- #include "Event.h"
- #include "EventStartSession.h"
- #include "EventPing.h"
- PtrReceiveMessage IRCSession::mRcvMsgFct;
- HANDLE IRCSession::mRunThread;
- bool IRCSession::mRunning;
- queue<SharedPointer<Event>> IRCSession::mEventQueue;
- CRITICAL_SECTION IRCSession::mSection;
- void IRCSession::OnReceiveCommand(ServerCommand cmd)
- {
- /*try
- {
- mRcvMsgFct(cmd.GetCommand().c_str());
- }
- catch (int e)
- {
- printf("error here");
- }
- */
- if(cmd.GetCommand().compare("PING") ==0)
- {
- SharedPointer<EventPing> evt(new EventPing(cmd.GetFinalParameter()));
- HandleEvent(evt);
- }
- else if(cmd.GetCommand().compare("433")==0)
- {
- mRcvMsgFct("Error your nickname is already used");
- //TODO : use alternative nick name or
- //dc the guy
- }
- else if(cmd.GetCommand().compare("PRIVMSG") ==0)
- {
- mRcvMsgFct(("[IRC]" + cmd.GetSender() + " > " +cmd.GetFinalParameter()).c_str());
- }
- }
- DWORD WINAPI IRCSession::Run(LPVOID lpParam)
- {
- while(mRunning)
- {
- EnterCriticalSection(&mSection);
- if(!mEventQueue.empty())
- {
- SharedPointer<Event> evt = mEventQueue.front();
- switch(evt->mType)
- {
- case EVT_START_SESSION:
- {
- mRcvMsgFct("Starting IRC Session...");
- SharedPointer<EventStartSession> sEvt = evt;
- if(Connection::Begin(sEvt->mServer)== CS_STARTED)
- {
- auto nickCommand = sEvt->mUser.GenerateNickNameCommand();
- Connection::SendUserCommand(*nickCommand);
- auto registerCommand = sEvt->mUser.GenerateRegisterUserCommand();
- Connection::SendUserCommand(*registerCommand);
- if(!sEvt->mUser.Password().empty())
- {
- auto identCommand = sEvt->mUser.GenerateIdentCommand();
- Connection::SendUserCommand(*identCommand);
- mRcvMsgFct("IRC Session started");
- }
- }
- else
- {
- mRcvMsgFct("Error starting irc Session");
- }
- }
- break;
- case EVT_RCV_PING:
- SharedPointer<EventPing> pEvt =evt;
- auto pongCommand = pEvt->mPing.GeneratePongCommand();
- Connection::SendUserCommand(*pongCommand);
- mRcvMsgFct(pongCommand->ToString().c_str());
- break;
- }
- mEventQueue.pop();
- }
- LeaveCriticalSection(&mSection);
- Sleep(100);
- }
- return 0;
- }
- void IRCSession::HandleEvent(SharedPointer<Event> evt)
- {
- EnterCriticalSection(&mSection);
- mEventQueue.push(evt);
- LeaveCriticalSection(&mSection);
- }
- void IRCSession::HandleChatBoxMssg(const char* msg)
- {
- char** words = GetWords(msg);
- unsigned int wordCount = GetWordCount(msg);
- if(wordCount >= 1)
- {
- if(words[0][0] != '/')
- {
- DeleteWords(words,wordCount);
- return; //it's not a command
- }
- char* cmd = words[0];
- if(!strcmp(cmd,"/helpirc"))
- {
- mRcvMsgFct("Here is the full list of available IRC commands :");
- mRcvMsgFct("/startirc 'ip' 'port' 'nickname' : start the irc");
- mRcvMsgFct("/joinchannel 'name'");
- mRcvMsgFct("/stopirc");
- }
- else if(!strcmp(cmd,"/startirc"))
- {
- if(wordCount >= 4)
- {
- mRunning = true;
- mRunThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Run,0,0,NULL);
- InitializeCriticalSection(&mSection);
- Server server;
- server.SetHost(words[1]);
- server.SetPort(atoi(words[2]));
- User user;
- user.UserName(words[3]);
- user.NickName(words[3]);
- if(wordCount == 5)
- {
- user.Password(words[4]);
- }
- else
- {
- user.Password("");
- }
- SharedPointer<EventStartSession> evt(new EventStartSession(user,server));
- HandleEvent(evt);
- }
- else
- {
- mRcvMsgFct("Wrong parameter count for /startirc");
- }
- }
- else if(!strcmp(cmd,"/stopirc"))
- {
- //should make an event to do : Connection::Close();
- Sleep(1000);
- mRunning = false;
- CloseHandle(mRunThread);
- DeleteCriticalSection(&mSection);
- mRcvMsgFct("IRC Connection stopped");
- }
- }
- DeleteWords(words,wordCount);
- }
- void IRCSession::SetReceiveMessageFunction(PtrReceiveMessage fct)
- {
- mRcvMsgFct = fct;
- }
- ********************************************************************************************
- #ifndef Ping_h__
- #define Ping_h__
- #include "UserCommand.h"
- #include "IncString.h"
- class Ping
- {
- public:
- std::auto_ptr<UserCommand> GeneratePongCommand()
- {
- std::auto_ptr<UserCommand> cmd (new UserCommand("PONG"));
- cmd->FinalParameter(mServerCode);
- return cmd;
- }
- public:
- string mServerCode;
- };
- #endif // Ping_h__
- ********************************************************************************************
- // #ifndef Null_h__
- #define Null_h__
- #ifndef NULL
- # define NULL 0
- #endif
- #define ISNULL(x) (x == NULL)
- #endif // Null_h__
- ********************************************************************************************
- #ifndef UserCommand_h__
- #define UserCommand_h__
- #include "IncString.h"
- #include "IncVector.h"
- class UserCommand
- {
- public :
- UserCommand(string command)
- {
- mCommand=command;
- }
- ~UserCommand()
- {
- }
- string GetCommand() const { return mCommand; }
- void SetCommand(string val) { mCommand = val; }
- void AddParameter(string val)
- {
- mParameter.push_back(val);
- }
- void DeleteParameter(unsigned int index)
- {
- if(index < mParameter.size())
- {
- mParameter.erase(mParameter.begin()+index);
- }
- }
- string FinalParameter() const { return mFinalParameter; }
- void FinalParameter(string val) { mFinalParameter = val; }
- string ToString()
- {
- string result = mCommand;
- for(int i = 0; i < mParameter.size();i++)
- {
- result.append(" ");
- result.append(mParameter[i]);
- }
- if(mFinalParameter.size()>0)
- {
- result.append(" : ");
- result.append(mFinalParameter);
- }
- return result;
- }
- private:
- string mCommand;
- vector<string> mParameter;
- string mFinalParameter;
- };
- #endif // UserCommand_h__
- ********************************************************************************************
- #ifndef RFCDefinition_h__
- #define RFCDefinition_h__
- #include <map>
- #include <string>
- using namespace std;
- /*
- map<int , string> gRFCNumbers;
- gRFCNumbers[1] = "";
- */
- #endif // RFCDefinition_h__
- ********************************************************************************************
- #ifndef SafeDelete_h__
- #define SafeDelete_h__
- #include "Null.h"
- #define SAFE_DELETE(x) if(x){ delete x; x = NULL; }
- #define SAFE_DELETE_2D(x, y) if(x){ for(unsigned int _i = 0; _i < y; ++_i){ delete x[_i]; } delete [] x; x = NULL; }
- #define SAFE_DELETE_ARRAY(x) if(x){ delete [] x; x = NULL; }
- #define SAFE_DELETE_ARRAY_2D(x, y) if(x){ for(unsigned int _i = 0; _i < y; ++_i){ delete [] x[_i]; } delete [] x; x = NULL; }
- #endif // SafeDelete_h__
- ********************************************************************************************
- #ifndef Server_h__
- #define Server_h__
- #include "IncString.h"
- class Server
- {
- public:
- string GetHost() const { return mHost; }
- void SetHost(string val) { mHost = val; }
- int GetPort() const { return mPort; }
- void SetPort(int val) { mPort = val; }
- private :
- string mHost;
- int mPort;
- };
- #endif // Server_h__
- ********************************************************************************************
- #include "ServerCommand.h"
- ServerCommand::ServerCommand()
- {
- }
- ServerCommand::~ServerCommand()
- {
- }
- void ServerCommand::Parse(char* s)
- {
- /*
- <message> ::= [':' <préfixe> <espace> ] <command> <params> <crlf>
- <préfixe> ::= <nom de serveur> | <pseudo> [ '!' <utilisateur> ] [ '@' <hôte> ]
- <command> ::= <lettre> { <lettre> } | <nombre> <nombre> <nombre>
- <espace> ::= ' ' { ' ' }
- <params> ::= <espace> [ ':' <fin> | <milieu> <params> ]
- <milieu> ::= <Toute séquence non vide d'octets à l'exclusion de ESPACE, NUL, CR, LF, le premier d'entre eux étant différent de ':'>
- <fin> ::= <Toute suite, éventuellement vide, d'octets, à l'exception de NUL, CR et LF>
- <crlf> ::= CR LF
- */
- //calcul du sender
- char* u = s;
- if(s[0] == ':')
- {
- while(*u && *u !=' ') u++;
- *u++ = '\0';
- string mSender = s+1;
- }
- else
- {
- string mSender = "";
- }
- //calcul de la commande
- char* v = u;
- while(*v && *v !=' ') v++;
- *v++ = '\0';
- mCommand = u;
- unsigned int paramsLength = 0;
- unsigned int i = 0;
- while(v[i] != ':' && i < strlen(v))
- {
- if(v[i] == ' ')
- {
- v[i] ='\0';
- mParameter.push_back(v+paramsLength);
- paramsLength=i+1;
- }
- i++;
- }
- if(v[i] == ':')
- {
- mFinalParameter = v + ++i ;
- }
- }
- ********************************************************************************************
- #ifndef ServerCommand_h__
- #define ServerCommand_h__
- #include "String.h"
- #include "IncVector.h"
- class ServerCommand
- {
- public :
- ServerCommand();
- ~ServerCommand();
- void Parse(char* s);
- string GetCommand() const { return mCommand; }
- void SetCommand(string val) { mCommand = val; }
- vector<string> GetParameter() const { return mParameter; }
- void SetParameter(vector<string> val) { mParameter = val; }
- std::string GetFinalParameter() const { return mFinalParameter; }
- void SetFinalParameter(std::string val) { mFinalParameter = val; }
- std::string GetSender() const { return mSender; }
- void SetSender(std::string val) { mSender = val; }
- string ToString()
- {
- string result = mCommand;
- for(int i = 0; i < mParameter.size();i++)
- {
- result.append(" ");
- result.append(mParameter[i]);
- }
- if(mFinalParameter.size()>0)
- {
- result.append(" : ");
- result.append(mFinalParameter);
- }
- return result;
- }
- private:
- string mSender;
- string mCommand;
- vector<string> mParameter;
- string mFinalParameter;
- };
- #endif // ServerCommand_h__
- ********************************************************************************************
- #ifndef SharedPointer_h__
- #define SharedPointer_h__
- template<class T> class SharedPointer
- {
- public:
- struct SmartObjet
- {
- public:
- SmartObjet(T* val) : mT(val),mReferenceCount(1){}
- unsigned long int mReferenceCount;
- T* mT;
- }* mObjet;
- public :
- typedef T elementType;
- explicit SharedPointer(T* t =0) : mObjet(0) {if(t)mObjet = new (nothrow) SmartObjet(t);}
- ~SharedPointer()
- {
- release();
- }
- SharedPointer(const SharedPointer & other) throw()
- {
- acquire(other.mObjet);
- }
- SharedPointer& operator=(SharedPointer const& other)
- {
- if(this != &other)
- {
- release();
- acquire(other.mObjet);
- }
- return *this;
- }
- T* operator->() const
- {
- return mObjet->mT;
- }
- T& operator*() const
- return *(mObjet->mT);
- }
- //Member templates
- template<class Y> SharedPointer(SharedPointer<Y> & other) throw()
- {
- acquire((SmartObjet*)other.mObjet);
- }
- template<class Y> SharedPointer& operator=(SharedPointer<Y> & other)
- {
- if(this != &other)
- {
- release();
- acquire(other.mObjet);
- }
- return *this;
- }
- T* get() const
- {
- return mObjet? mObjet->mT : 0;
- }
- bool unique()
- {
- return mObjet? (mObjet->mReferenceCount ==1) : true;
- }
- unsigned long int use_count()
- {
- return mObjet? mObjet->mReferenceCount : 0;
- }
- void swap(SharedPointer& other)
- {
- SmartObjet* temp = mObjet;
- mObjet = other.mObjet;
- other.mObjet = temp;
- }
- bool operator==(SharedPointer& other)
- {
- return (mObjet == other.mObjet);
- }
- bool operator!=(SharedPointer& other)
- {
- return !(*this == other);
- }
- public :
- void release()
- {
- if(mObjet)
- {
- mObjet->mReferenceCount--;
- if(!mObjet->mReferenceCount && mObjet->mT)
- {
- delete mObjet->mT;
- }
- }
- }
- void acquire(SmartObjet* obj) throw()
- {
- mObjet = obj;
- if(mObjet) obj->mReferenceCount++;
- }
- };
- #endif // SharedPointer_h__
- ********************************************************************************************
- #ifndef User_h__
- #define User_h__
- #include <memory>
- class UserCommand;
- class User
- {
- public :
- string NickName() const { return mNickName; }
- void NickName(string val) { mNickName = val; }
- std::auto_ptr<UserCommand> GenerateNickNameCommand()
- {
- std::auto_ptr<UserCommand> usrcmd(new UserCommand("NICK"));
- usrcmd->AddParameter(mNickName);
- return usrcmd;
- }
- std::auto_ptr<UserCommand> GenerateRegisterUserCommand()
- {
- std::auto_ptr<UserCommand> usrcmd(new UserCommand("USER"));
- usrcmd->AddParameter(mUserName);
- usrcmd->AddParameter("0");
- usrcmd->AddParameter("*");
- usrcmd->FinalParameter(mUserName);
- return usrcmd;
- }
- std::auto_ptr<UserCommand> GenerateIdentCommand()
- {
- std::auto_ptr<UserCommand> usrcmd(new UserCommand("AUTH"));
- usrcmd->AddParameter(mNickName);
- usrcmd->AddParameter(mPassword);
- return usrcmd;
- }
- string UserName() const { return mUserName; }
- void UserName(string val) { mUserName = val; }
- int Mode() const { return mMode; }
- void Mode(int val) { mMode = val; }
- std::string Password() const { return mPassword; }
- void Password(std::string val) { mPassword = val; }
- private :
- string mUserName;
- string mNickName;
- string mPassword;
- int mMode;
- };
- #endif // User_h__
- ********************************************************************************************
Add Comment
Please, Sign In to add comment