Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "IRC.h"
- static void mysleep( unsigned long long d ){
- #ifdef __WIN32
- Sleep( d );
- #else
- usleep( d * 1000 );
- #endif
- }
- static std::string str_lwr( std::string in ){
- std::string out = "";
- for( unsigned int i = 0; i < in.length(); ++i ){
- out += tolower( in[i] );
- }
- return out;
- }
- void IRC::senda( SOCKET sock, const char* str )
- {
- #ifdef DEBUG
- printf(">>%s\n", str);
- #endif
- send( sock, str, strlen( str ), 0 );
- }
- void IRC::sendb( SOCKET sock, const char* str1, const char* str2 )
- {
- char sendbuf[1000];
- sprintf( sendbuf, "%s%s", str1, str2 );
- senda( sock, sendbuf );
- }
- unsigned long IRC::resolveAddr( const char* addr, int ind)
- {
- hostent* host = gethostbyname( addr );
- if( host == 0 )
- {
- printf( "Failed to lookup %s.", addr );
- return 0;
- }
- if( ind > host->h_length ) return -1;
- unsigned long myhost = *((unsigned long*) host->h_addr);//_list[host->h_length - ind];
- //printf( "%Host: %i.%i.%i.%i\n", myhost & 0xFF, ( myhost >> 8 ) & 0xFF, ( myhost >> 16 ) & 0xFF, ( myhost >> 24 ) & 0xFF );
- return myhost;
- }
- char* IRC::getMessage( SOCKET recvOn, char* buffer, int len )
- {
- char tmp = 0;
- int pos = 0;
- int val = 1;
- //printf( "aloal" );
- val = recv( recvOn, &tmp, 1, 0 );
- if( val == 0 )
- {
- buffer[0] = 0;
- return (char*)0;
- }
- if( val < 0 )
- {
- buffer[0] = 0;
- return 0;
- }
- //printf( "aloal" );
- while( tmp != '\n' && val > 0 )
- {
- if( pos >= len ){
- buffer[pos] = 0;
- if( buffer[pos-1] == '\r' )
- buffer[pos-1] = 0;
- return buffer;
- }
- //printf( "aloal" );
- //if( tmp > 28 )
- buffer[pos++] = tmp;
- val = recv( recvOn, &tmp, 1, 0 );
- if( val <= 0 )
- {
- buffer[pos] = 0;
- if( buffer[pos-1] == '\r' )
- buffer[pos-1] = 0;
- return buffer;
- }
- }
- if( buffer[pos-1] == '\r' )
- buffer[pos-1] = 0;
- buffer[pos++] = 0;
- return buffer;
- }
- SOCKET IRC::connectTCP( unsigned long ip, short int port )
- {
- SOCKET ret;
- ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if( ret < 0 ) return 0;
- sockaddr_in clientService;
- clientService.sin_family = AF_INET;
- clientService.sin_addr.s_addr = ip;
- clientService.sin_port = htons( port );
- int result = connect( ret, (sockaddr*) &clientService, sizeof(clientService));
- if( result < 0 ) return 0;
- return ret;
- }
- void IRC::sendMsg( SOCKET tosend, const char* format, ... )
- {
- char sendBuf[1000];
- va_list strt;
- va_start( strt, format );
- vsprintf( sendBuf, format, strt );
- va_end( strt );
- sendb( tosend, sendBuf, (const char*) "\r\n" );
- }
- void IRC::sendMsg( bool partial, const char* format, ... )
- {
- char sendBuf[1000];
- va_list strt;
- va_start( strt, format );
- vsprintf( sendBuf, format, strt );
- va_end( strt );
- senda( sock, sendBuf );
- if( !partial )
- senda( sock, "\r\n" );
- }
- void* IRC::thread::malloc( size_t len ){
- void* t = ::malloc( len );
- mallocs.push_back( t );
- return t;
- }
- void IRC::thread::free( void* val ){
- if( val == 0 ) return;
- for( unsigned int i = 0; i < mallocs.size(); ++i )
- if( mallocs[i] == val ){
- ::free( mallocs[i] );
- mallocs[i] = 0;
- break;
- }
- }
- void IRC::thread::freeall(){
- for( unsigned int i = 0; i < mallocs.size(); ++i )
- if( mallocs[i] != 0 )
- ::free( mallocs[i] );
- mallocs.resize(0,0);
- }
- void IRC::callback_privmsg(SOCKET sock, std::string msg, IRC::user sender, void* d){
- std::string v = msg.substr( 0, msg.find_first_of( ' ' ) );
- IRC::destination dst;
- dst.v = v;
- dst.type = 0;
- if( v[0] == '#' )
- dst.type = 1;
- else
- dst.v = sender.nick;
- IRC* irc = (IRC*) d;
- std::string tmp = msg.substr(msg.find_first_of( ':' ) + 1);
- std::string tmp2 = str_lwr( tmp );
- for( unsigned int i = 0; i < irc->ccb.size(); ++i ){
- if( tmp2.find( irc->ccb[i].v ) == 0 ){
- irc->ccb[i].call( sock, tmp, sender, dst, irc->ccb[i].d );
- }
- }
- }
- void IRC::callback_ping(SOCKET sock, std::string msg, IRC::user sender, void*){
- msg[1] = 'O';
- sendMsg( sock, "%s", msg.c_str() );
- }
- void IRC::pushcallback( std::string type, void* d, void (*call)( SOCKET sock, std::string msg, IRC::user sender, void* ) ){
- callback a;
- a.v = str_lwr(type);
- a.d = d;
- a.call = call;
- cb.push_back( a );
- }
- void IRC::pushchatcallback( std::string type, void* d, void (*call)( SOCKET sock, std::string msg, IRC::user sender, IRC::destination dst, void* ) ){
- chatcallback a;
- a.v = str_lwr(type);
- a.d = d;
- a.call = call;
- ccb.push_back( a );
- }
- void IRC::docallback( std::string raw ){
- user a;
- a.n = true;
- a.nick = a.user = a.host = "";
- int t = 0;
- int t2 = 0;
- if( raw[0] == ':' ){
- t = 1;
- t2 = raw.find_first_of( '!', t );
- a.nick = raw.substr( 1, t2 - t );
- t = t2 + 1;
- t2 = raw.find_first_of( '@', t );
- a.user = raw.substr( 1, t2 - t );
- t = t2 + 1;
- t2 = raw.find_first_of( ' ', t );
- a.host = raw.substr( 1, t2 - t );
- a.n = false;
- t = t2 + 1;
- }
- t2 = raw.find_first_of( ' ', t );
- std::string type = str_lwr(raw.substr( t, t2 - t ));
- for( unsigned int i = 0; i < cb.size(); ++i ){
- if( type == cb[i].v)
- cb[i].call( sock, raw.substr(t2+1), a, cb[i].d );
- }
- }
- void IRC::main_loop(){
- char buf[5001];
- while( time(0) < connecttime + 3 ){
- mysleep( 100 );
- }
- docallback( "CONNECT" );
- while( true ){
- if( getMessage( sock, buf, 5000 ) == 0 ) break;
- #ifdef DEBUG
- printf("<<%s\n", buf);
- #endif
- std::string a = buf;
- docallback( a );
- }
- }
- IRC::IRC( std::string nick, std::string user, std::string realname, std::string server, int port ){
- #ifdef __WIN32
- WSADATA globalWSAData;
- WSAStartup( MAKEWORD(2, 2), &globalWSAData );
- #endif
- valid = false;
- sock = connectTCP( resolveAddr( server.c_str() ), port );
- if( sock <= 0 ) { return; }
- pushcallback( "PRIVMSG", (void*) this, callback_privmsg );
- pushcallback( "PING", (void*) this, callback_ping );
- valid = true;
- sendMsg( sock, "NICK %s", nick.c_str() );
- sendMsg( sock, "USER %s %s %s :%s", user.c_str(), user.c_str(), user.c_str(), realname.c_str() );
- connecttime = time( 0 );
- }
- int IRC::isvalid(){
- return valid;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement