// ogcircc.cpp : Defines the entry point for the console application.
//

#define DLL_COMPILE
//#undef DLL_COMPILE

#ifdef DLL_COMPILE
#include <stdio.h>
#include <windows.h>
#endif


#include "stdafx.h"
#include "winsock.h"

struct paramstru {
	u_short port;
	char host[256];
	char channel[256];
	char nick[256];
	SOCKET sd;
	void (*meldefunc)(char*);
};

char toplinebuffer[512];

DWORD ircthread(paramstru* param)
{
	char superbuffer[2048];
	WSADATA wsaData;
	WSAStartup(0x0101, &wsaData);
	struct  sockaddr_in sad;
	memset((char *)&sad,0,sizeof(sad));
	sad.sin_family = AF_INET;  
	sad.sin_port = htons(param->port);
	struct  hostent  *ptrh;
	ptrh = gethostbyname(param->host);
	if (!ptrh)
	{
		param->meldefunc("&xcould not resolve irc server\n");
		return 0;
	}
	memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
	struct  protoent *ptrp;
	ptrp = getprotobyname("tcp");
	SOCKET sd;
	sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
	param->sd=sd;
	if (sd < 0) {
		param->meldefunc("&xsocket creation failed\n");
		return 0;
	}
	if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
		param->meldefunc("&xconnect failed\n");
		return 0;
	}
	sprintf(superbuffer,"USER %s %s %s :%s\nNICK %s\n","ogcchat","127.0.0.1","ircserver","OGC IRC Client (www.system.cd)",param->nick);
	send(sd,superbuffer,strlen(superbuffer),0); 
	int n;
	char buf[1000];
	memset(superbuffer,0,sizeof(superbuffer));
	n = recv(sd, buf, sizeof(buf), 0);
	while (n > 0) {
		buf[n]=0x0;
		strcat(superbuffer,buf);
		char* pos = strchr(superbuffer,13);
		while (pos) {
			DWORD bufsize= pos-superbuffer;
			char tempbuf[512];
			strncpy(tempbuf,superbuffer,bufsize);
			tempbuf[bufsize]=0x0;
			bufsize+=2;
			memcpy(superbuffer,superbuffer+bufsize,sizeof(superbuffer)-bufsize);
			if (!strncmp(tempbuf,"PING",4))
			{
				char *reply = new char[strlen(tempbuf)+2];
				sprintf(reply,"%s\n",tempbuf);
				reply[1]='O';
				send(sd,reply,strlen(reply),0);
				delete [] reply;
			}
			else 
			{
				char* spacer = strchr(tempbuf,' ');
				if (spacer)
				{
					spacer+=1;
					if (!strncmp(spacer,"376",3))
					{
						char sendbuf[256];
						sprintf(sendbuf,"JOIN %s\n",param->channel);
						send(sd,sendbuf,strlen(sendbuf),0);
					}
					else
						if ((!strncmp(spacer,"PRIVMSG",7))||(!strncmp(spacer,"NOTICE",6)))
						{
							char nick[256];
							DWORD len=spacer-tempbuf;
							strncpy(nick,tempbuf+1,len-1);
							nick[len-2]=0x0;
							char* evil = strchr(nick,'!');
							if (evil) *evil=0x0;
							char printfbuffer[512];
							if ((spacer[8]=='#') || (spacer[8]=='&'))
								sprintf(printfbuffer,"&w%s:&b %s\n",nick,strchr(spacer,':')+1);
							else sprintf(printfbuffer,"&w%s&x(private)&w:&b %s\n",nick,strchr(spacer,':')+1);
							param->meldefunc(printfbuffer);
						}
						else if (!strncmp(spacer,"JOIN",4))
						{
							char nick[256];
							DWORD len=spacer-tempbuf;
							strncpy(nick,tempbuf+1,len-1);
							nick[len-2]=0x0;
							char* evil = strchr(nick,'!');
							if (evil) *evil=0x0;
							char printfbuffer[512];
							sprintf(printfbuffer,"&y%s&b joined &y%s\n",nick,param->channel);
							param->meldefunc(printfbuffer);
						}
						else if (!strncmp(spacer,"QUIT",4))
						{
							char nick[256];
							DWORD len=spacer-tempbuf;
							strncpy(nick,tempbuf+1,len-1);
							nick[len-2]=0x0;
							char* evil = strchr(nick,'!');
							if (evil) *evil=0x0;
							char printfbuffer[512];
							sprintf(printfbuffer,"&y%s&b disconneted\n",nick);
							param->meldefunc(printfbuffer);
						}
						else if (!strncmp(spacer,"PART",4))
						{
							char nick[256];
							DWORD len=spacer-tempbuf;
							strncpy(nick,tempbuf+1,len-1);
							nick[len-2]=0x0;
							char* evil = strchr(nick,'!');
							if (evil) *evil=0x0;
							char printfbuffer[512];
							sprintf(printfbuffer,"&y%s&b left &y%s\n",nick,param->channel);
							param->meldefunc(printfbuffer);
						}
						else if (!strncmp(spacer,"MODE",4))
						{
							char nick[256];
							DWORD len=spacer-tempbuf;
							strncpy(nick,tempbuf+1,len-1);
							nick[len-2]=0x0;
							char* evil = strchr(nick,'!');
							if (evil) *evil=0x0;
							char printfbuffer[512];
							sprintf(printfbuffer,"&y%s&b sets mode &y%s\n",nick,strchr(spacer,' ')+1);
							param->meldefunc(printfbuffer);
						}
						else if (!strncmp(spacer,"NICK",4))
						{
							char nick[256];
							DWORD len=spacer-tempbuf;
							strncpy(nick,tempbuf+1,len-1);
							nick[len-2]=0x0;
							char* evil = strchr(nick,'!');
							if (evil) *evil=0x0;
							char printfbuffer[512];
							sprintf(printfbuffer,"&y%s&b changes nick to &y%s\n",nick,strchr(spacer,' ')+1);
							param->meldefunc(printfbuffer);
						}
						else if (!strncmp(spacer,"KICK",4))
						{
							char nick[256];
							DWORD len=spacer-tempbuf;
							strncpy(nick,tempbuf+1,len-1);
							nick[len-2]=0x0;
							char* evil = strchr(nick,'!');
							if (evil) *evil=0x0;
							char printfbuffer[512];
							sprintf(printfbuffer,"&y%s&b kicked &y%s\n",nick,strchr(spacer,' ')+1);
							param->meldefunc(printfbuffer);
						}
						else
						{
							char buffi[512];
							sprintf(buffi,"&y%s\n",tempbuf);
							param->meldefunc(buffi);
						}
				}

			}
			pos = strchr(superbuffer,13);
		}
		n = recv(sd, buf, sizeof(buf), 0);
	}
	param->meldefunc("&xconnection closed\n");
	closesocket(sd);
	WSACleanup();
	return 0;
}

static paramstru someparam;



#ifdef DLL_COMPILE

extern "C"{
__declspec(dllexport) char* getTopLine()
{
   return toplinebuffer;
}
}
	extern "C"{
	__declspec(dllexport) 
	void IrcSubmit( char* text )
#else
	void IrcSubmit(char* text)
#endif
{
	if (!strcmp(text,"")) return;
	if (text[0]=='/')
	{
		text++;
		strlwr(text);
		if (!strncmp(text,"connect",7))
		{
			text+=7;
			if(*text) 
			{
				text++;
			char buffo[256];
			char* channel = strchr(text,' ');
			if (channel)
			{
			strncpy(someparam.host,text,channel-text);
			someparam.host[channel-text]=0x0;
			someparam.port=6667;
			channel++;
			char* nick = strchr(channel,' ');
			if (nick)
			{
			strncpy(someparam.channel,channel,nick-channel);
			someparam.channel[nick-channel]=0x0;
			nick++;
			strcpy(someparam.nick,nick);
			sprintf(buffo,"&xtrying to connect to %s\n",someparam.host);
			someparam.meldefunc(buffo);
			sprintf(buffo,"&xusing channel %s and nick %s\n",someparam.channel,someparam.nick);
			someparam.meldefunc(buffo);

			DWORD tid;
			HANDLE thethread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)&ircthread,&someparam,NULL,&tid);
			} else someparam.meldefunc("&xnot enough parameters\n");
			} else someparam.meldefunc("&xnot enough parameters\n");
			} else someparam.meldefunc("&xnot enough parameters\n");
		} 
		else if ((!strncmp(text,"quit",4)) || (!strncmp(text,"disconnect",10)) )
		{
		send(someparam.sd,"quit :ogc irc client\n",strlen("quit :ogc irc client\n"),0);
		}
		else 
			someparam.meldefunc("&xunknown command\n");
	} else
	if (someparam.sd)
	{
		char buffa[512];
		sprintf(buffa,"PRIVMSG %s :%s\n",someparam.channel,text);
		send(someparam.sd,buffa,strlen(buffa),0);
		sprintf(buffa,"&r%s:&b %s\n",someparam.nick,text);
		someparam.meldefunc(buffa);
	}
}
#ifdef DLL_COMPILE
	}//extern "C" 
#endif


#ifdef DLL_COMPILE
	BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,struct mydata* lpReserved)
	{
		return TRUE;
	}
	extern "C"{
	__declspec(dllexport) 
	int IrcInitialize( void(*echoCallBack)(char* text) )
	{
		someparam.meldefunc = echoCallBack;
		someparam.meldefunc( "plugin_irc.dll: loaded." );
		return 0;
	}
	}//extern "C" 
#else
	void somemeldefunc(char* param)
	{
		printf("%s",param);
	}

	int _tmain(int argc, _TCHAR* argv[])
	{
		// always has to be set
		someparam.meldefunc = &somemeldefunc;

		while (true) {
			char buffa[1024];
			gets(buffa);
			IrcSubmit(buffa);
		}
		return 0;
	}
#endif

