Beispiel #1
0
static void* MainChatbotServer()
{
	sprintf(serverLogfileName,"LOGS/serverlog%d.txt",port);
	ServerStartup(); //   get initial control over the mutex so we can start. - on linux if thread dies, we must reacquire here 
	// we now own the chatlock
	clock_t lastTime = ElapsedMilliseconds(); 

	if (setjmp(scriptJump[MAIN_RECOVERY])) // crashes come back to here
	{
		printf("***Server exception\r\n");
		ReportBug("***Server exception\r\n");
#ifdef WIN32
		char* bad = GetUserVariable("$crashmsg");
		if (*bad) strcpy(outputFeed,bad);
		else strcpy(outputFeed,"Hey, sorry. I forgot what I was thinking about.");
		ServerTransferDataToClient("");
#endif
		ResetBuffers(); //   in the event of a trapped bug, return here, we will still own the chatlock
	}
    chatbotExists = true;   //  if a client can get the chatlock now, he will be happy
	Log(SERVERLOG,"Server ready\r\n");
	printf("Server ready: %s\r\n",serverLogfileName);
#ifdef WIN32
 _try { // catch crashes in windows
#endif
	int counter = 0;
	while (1)
	{
		ServerGetChatLock();
		startServerTime = ElapsedMilliseconds(); 

		// chatlock mutex controls whether server is processing data or client can hand server data.
		// That we now have it means a client has data for us.
		// we own the chatLock again from here on so no new client can try to pass in data. 
		// CLIENT has passed server in globals:  clientBuffer (ip,user,bot,message)
		// We will send back his answer in clientBuffer, overwriting it.
		char user[MAX_WORD_SIZE];
		char bot[MAX_WORD_SIZE];
		char* ip = clientBuffer;
		char* ptr = ip;
		// incoming is 4 strings together:  ip, username, botname, message
		ptr += strlen(ip) + 1;	// ptr to username
		strcpy(user,ptr); // allow user var to be overwriteable, hence a copy
		ptr += strlen(ptr) + 1; // ptr to botname
		strcpy(bot,ptr);
		ptr += strlen(ptr) + 1; // ptr to message
		strcpy(inputFeed,ptr); // xfer user message to our incoming feed
		echo = false;

		PerformChat(user,bot,inputFeed,ip,outputFeed);	// this takes however long it takes, exclusive control of chatbot.
#ifdef STATSERVER
		clock_t now = ElapsedMilliseconds();
		if ( (now / 1000) > (lastTime / 1000)) // starting different second
		{
			printf("%d\r\n",counter);
			counter = 0;
			lastTime = now; 
		}
		++counter;
		if ((now-startServerTime) > 2000) 
		{
			printf("Compute Stall? %d\r\n",now-startServerTime);
		}
#endif		
	ServerTransferDataToClient(priorMessage);
	}
#ifdef WIN32
		}_except (true) {
			ReportBug("crash\r\n"); Crash();}
#endif
	return NULL;
}
VOID CALLBACK TimeCheck( HWND hwnd, UINT uMsg,UINT_PTR idEvent,DWORD dwTime) // every 100 ms
{
	char c;
	static bool init = false;
	static int inputCount = 0;
	if (!init)
	{
		init = true;
	//	char word[MAX_WORD_SIZE];
	//	GetCurrentDir(word, MAX_WORD_SIZE);
		InitChatbot(computerName);
		RECT rect;
		GetClientRect(hwnd, &rect);
		InvalidateRect(hwnd, &rect, TRUE);
		strcpy(response,"Chatbot initialization complete");
	}

	static int counter = 0;
	++counter; // increament each timer interrupt, tracking how long since last key input from user
	static char lastchar = 0;
	static bool keyhit = false;
	while ((c = ReadChar())) // returns 0 if nothing found
	{
		keyhit = true; // user input seen since last output
		RECT rect;
		GetClientRect(hwnd, &rect);
		InvalidateRect(hwnd, &rect, TRUE);
		if ( c == 8) // backspace
		{
			if ( msgPtr != inputMessage) *--msgPtr = 0;
		}
		else if ( c == '\n' || c == '\r') // prepare for NEW input and get response
		{
			if (msgPtr == inputMessage) continue;	// ignore empty lines
			*msgPtr = 0;
			counter = 100;	// treat as end of input
			break;	// dont read until we have responded
		}
		else if (msgPtr == inputMessage && (c == ' ' || c == '\t' )) continue;	// ignore leading whitespace.
		else // accept new character
		{
			*msgPtr++ = c;
			lastchar = c;
			*msgPtr = 0;
		}
		counter = 0; // start time wait over again
	}

	// do we have something we want to respond to?
	bool trigger = false;
	if (counter >= 30 && *inputMessage && (lastchar == '.' || lastchar == '?' || lastchar == '!')) trigger = true; // 3 sec passed and have input ended on closer 
	else if (counter >= 70 && *inputMessage) trigger = true; // 7 seconds + have lingering input
	// or timer oob goes off
	char oob[MAX_WORD_SIZE];
	*oob = 0;
	ProcessInputDelays(oob,keyhit); 

	if (trigger || *oob)
	{
		if (*oob) strcpy(ourMainInputBuffer,oob); // priority is to alarm callback. others will be only if no user input anyway
		else  
		{
			strcpy(ourMainInputBuffer,inputMessage);
			// clear all signs of user input
			lastchar = 0;	
			*inputMessage = 0;
			msgPtr = inputMessage;
			keyhit = false;
		}

		PerformChat(loginID,computerID,ourMainInputBuffer,NULL,ourMainOutputBuffer);
		strcpy(response,ourMainOutputBuffer);
		callBackDelay = 0; // now turned off after an output
		ProcessOOB(ourMainOutputBuffer); // process relevant out of band messaging and remove

		char word[MAX_WORD_SIZE];
		char* p = SkipWhitespace(ourMainOutputBuffer);
		ReadCompiledWord(p,word);
		if (!*word) strcpy(p,"huh?"); // in case we fail to generate output

		// transmit message to user
		++inputCount;
		while (*p) 
		{
			if (SendChar(*p,p[1],inputCount)) p++; // got sent
		}
		SendChar('\n',0,inputCount);
		if (loopBackDelay) loopBackTime = ElapsedMilliseconds() + loopBackDelay; // resets every output

		// write out last sequence id
		FILE* out = fopen("sequence", "wb");
		fprintf(out,"%d",sequence);
		fclose(out);

		counter = 0;
		RECT rect;
		GetClientRect(hwnd, &rect);
		InvalidateRect(hwnd, &rect, TRUE);
	}
}