www.pudn.com > inet_stock.zip > HQDEST.C


#include 
#include "hq.h"
#include "pctcp.h"
#include "hqdest.h"

DEST_INFOS dest_infos;
BOOL fDestInited =FALSE;
HANDLE hThrdScanDest =NULL;

void FreeDest(void);
LPDEST_INFO GetDest(struct sockaddr *dest);
LPDEST_INFO GetDestByUser(LPSTR userID);
LPDEST_INFO GetFirstDeadDest(void);
int FillDpMain(LPDP_MAIN lpDpMain);

extern HWND ghWndMain;
extern BOOL run_cancelled;
extern void ErrMsg(HWND, LPSTR);
extern int UDP_Server_Send_Hq10(LPDEST_INFO);
extern int UDP_Server_Send_Gra10(LPDEST_INFO);
extern int UDP_Server_Send_Dp(struct sockaddr *, BOOL);
extern void HqResetChangedTimes(void);
extern void SetHqUsers(int);
extern BOOL IsZsRec(int, short);
extern int sdHq;
extern void SendMsg(int sd, LPSTR lpMsg, struct sockaddr * lpdest);
BOOL DestInit(void)
{
	fDestInited =TRUE;
	memset(&dest_infos, 0, sizeof(dest_infos));
	return TRUE;
}

void DestExit(void)
{
	if(!fDestInited) return;
	fDestInited =FALSE;
	FreeDest();
	if(hThrdScanDest) CloseHandle(hThrdScanDest);
}

long GetDestCount(void)
{
	return MAKELONG(dest_infos.destCount, dest_infos.aliveCount);
}

int HqDestActiveUsr(int sd, struct sockaddr *lpdest, LPSTR userID)
{
	LPDEST_INFO lpDestTmp, lpDestTmp1;
	
	lpDestTmp =GetDest(lpdest);
	if(lpDestTmp ==NULL)return -1;
	lpDestTmp1 =GetDestByUser(userID);
	if(lpDestTmp1 !=NULL)
	{
		if(lpDestTmp1->isDead ==FALSE)
		{
			if(((struct sockaddr_in *)&lpDestTmp1->dest)->sin_addr.s_addr
				!=((struct sockaddr_in *)lpdest)->sin_addr.s_addr)
				SendMsg(sd, "Another user using your userID, killed it!", lpdest);
			lpDestTmp1->isDead =TRUE;
			return 1;
		}
	}
	strcpy(lpDestTmp->userID, userID);
	lpDestTmp->isDead =FALSE;
	
	return 0;
}

int AddDest(int sd, struct sockaddr *dest, int curJys,
			int reqType, short *params, short paramsCount)
{
	int i;
	LPDEST_INFO lpDestNext, lpDestTmp;
	LPDEST_INFO *lpDestNew =NULL;
	//while(dest_infos.isUsing ==TRUE);
	//dest_infos.isUsing =TRUE;
	
	lpDestNext =dest_infos.lpDestHead;
	lpDestNew =&dest_infos.lpDestHead;

	for(i =0; ilpNext;
		lpDestNext =lpDestNext->lpNext;
	}

	lpDestTmp = malloc(sizeof(DEST_INFO));
	if(lpDestTmp ==NULL)
	{
		ErrMsg(ghWndMain, "addDest: alloc dest_info failed!");
		return -1;
	}
	memset(lpDestTmp, 0, sizeof(DEST_INFO));
	lpDestTmp->sd =sd;
	lpDestTmp->curJys =curJys;
	lpDestTmp->reqType =reqType;
	lpDestTmp->isDead =FALSE;
	lpDestTmp->isEchoed =TRUE;
	lpDestTmp->params =(short *)malloc(paramsCount*sizeof(short));
	if(lpDestTmp->params ==NULL)
	{
		free(lpDestTmp);
		ErrMsg(ghWndMain, "addDest: alloc params failed!");
		return -1;
	}
	memcpy(lpDestTmp->params, params, sizeof(short)*paramsCount);
	if(reqType ==REQ_HQ10)
	{
		lpDestTmp->lpCjss =(int *)malloc(params[0]*sizeof(int));
		if(lpDestTmp->lpCjss ==NULL)
		{
			free(lpDestTmp->params);
			free(lpDestTmp);
			ErrMsg(ghWndMain, "addDest: alloc lpCjss failed!");
			return -1;
		}
		for(i =0; ilpCjss[i] =HqData[curJys].lpRefData[params[i+1]].cjss;
		}
	}
	else if(reqType ==REQ_GRA10)
	{
		if(lpDestTmp->lpCjss)
		{
			free(lpDestTmp->lpCjss);
			lpDestTmp->lpCjss =NULL;
		}
		if(IsZsRec(curJys, params[0]))
		{
			lpDestTmp->lpZsGraph =malloc(sizeof(ZS_GRAPH));
			if(lpDestTmp->lpZsGraph ==NULL)
			{
				free(lpDestTmp->params);
				free(lpDestTmp);
				ErrMsg(NULL, "alloc zsgraph failed!");
				return -1;
			}
			memcpy(lpDestTmp->lpZsGraph->Maxmin, MaxMinData[curJys],
					sizeof(MAXMIN_DATA)*2);
		}
		else
		{
			lpDestTmp->lpGraph =(LPGRAPH)malloc(sizeof(GRAPH));
			if(lpDestTmp->lpGraph ==NULL)
			{
				free(lpDestTmp->params);
				free(lpDestTmp);
				ErrMsg(NULL, "alloc graph failed!");
				return -1;
			}
			memcpy(&lpDestTmp->lpGraph->mmp, &MmpData[curJys].lpMmp[params[0]],
					sizeof(MMP));
		}
		lpDestTmp->cjss =HqData[curJys].lpRefData[params[0]].cjss;
	}
	else
	{
		free(lpDestTmp->params);
		free(lpDestTmp);
		return -1;
	}

	FillDpMain(&lpDestTmp->DpData[0]);
	
	lpDestTmp->paramsCount =paramsCount;
	memcpy(&lpDestTmp->dest, dest, sizeof(struct sockaddr));
	lpDestTmp->isDead =TRUE;
	*lpDestNew =lpDestTmp;

	dest_infos.destCount ++;
	dest_infos.aliveCount ++;
	//dest_infos.isUsing =FALSE;

	return 0;
}

int ChangeDest(int sd, LPDEST_INFO lpDestTmp, struct sockaddr *dest, int curJys,
			int reqType, short *params, short paramsCount)
{
	int i;
	
	if(lpDestTmp ==NULL) return 0;

	//while(dest_infos.isUsing ==TRUE);
	//while(lpDestTmp->isUsing ==TRUE);
	
	dest_infos.isUsing =TRUE;
	lpDestTmp->isUsing =TRUE;
	
	lpDestTmp->isDead =TRUE;
	lpDestTmp->paramsCount =0;
	if(--dest_infos.aliveCount<0) dest_infos.aliveCount =0;
	SetHqUsers(dest_infos.aliveCount);
	
	lpDestTmp->sd =sd;
	lpDestTmp->curJys =curJys;
	lpDestTmp->reqType =reqType;
	lpDestTmp->isEchoed =TRUE;
	if(lpDestTmp->paramsCount params =(short *)realloc(lpDestTmp->params, paramsCount*sizeof(short));
	if(lpDestTmp->params ==NULL)
	{
		ErrMsg(ghWndMain, "ChangeDest: alloc params failed!");
		dest_infos.isUsing =FALSE;
		lpDestTmp->isUsing =FALSE;
		return -1;
	}
	if(reqType ==REQ_HQ10)
	{
		/*if(lpDestTmp->lpGraph)
		{
			free(lpDestTmp->lpGraph);
			lpDestTmp->lpGraph =NULL;
		}
		if(lpDestTmp->lpZsGraph)
		{
			free(lpDestTmp->lpZsGraph);
			lpDestTmp->lpZsGraph =NULL;
		}*/
		if(lpDestTmp->params[0] lpCjss =(int *)realloc(lpDestTmp->lpCjss, params[0]*sizeof(int));
		if(lpDestTmp->lpCjss ==NULL)
		{
			ErrMsg(ghWndMain, "ChangeDest: alloc lpCjss failed!");
			dest_infos.isUsing =FALSE;
			lpDestTmp->isUsing =FALSE;
			return -1;
		}
		for(i =0; ilpCjss[i] =HqData[curJys].lpRefData[params[i+1]].cjss;
		}
	}
	else if(reqType ==REQ_GRA10)
	{
		/*if(lpDestTmp->lpCjss)
		{
			free(lpDestTmp->lpCjss);
			lpDestTmp->lpCjss =NULL;
		}*/
		if(IsZsRec(curJys, params[0]))
		{
			/*if(lpDestTmp->lpGraph)
			{
				free(lpDestTmp->lpGraph);
				lpDestTmp->lpGraph =NULL;
			}*/
			if(lpDestTmp->lpZsGraph ==NULL)
			{
				lpDestTmp->lpZsGraph =malloc(sizeof(ZS_GRAPH));
				if(lpDestTmp->lpZsGraph ==NULL)
				{
					ErrMsg(NULL, "alloc zsgraph failed!");
					return -1;
				}
			}
			memcpy(lpDestTmp->lpZsGraph->Maxmin, MaxMinData[curJys],
					sizeof(MAXMIN_DATA)*2);
		}
		else
		{
			/*if(lpDestTmp->lpZsGraph)
			{
				free(lpDestTmp->lpZsGraph);
				lpDestTmp->lpZsGraph =NULL;
			}*/
			if(lpDestTmp->lpGraph ==NULL)
			{
				lpDestTmp->lpGraph =(LPGRAPH)malloc(sizeof(GRAPH));
				if(lpDestTmp->lpGraph ==NULL)
				{
					ErrMsg(NULL, "alloc graph failed!");
					return -1;
				}
			}
			memcpy(&lpDestTmp->lpGraph->mmp, &MmpData[curJys].lpMmp[params[0]],
					sizeof(MMP));
		}
		lpDestTmp->cjss =HqData[curJys].lpRefData[params[0]].cjss;
	}
	else return -1;
	memcpy(lpDestTmp->params, params, sizeof(short)*paramsCount);
	
	FillDpMain(&lpDestTmp->DpData[0]);
	
	memcpy(&lpDestTmp->dest, dest, sizeof(struct sockaddr));
	lpDestTmp->paramsCount =paramsCount;

	dest_infos.isUsing =FALSE;
	lpDestTmp->isUsing =FALSE;
	lpDestTmp->isDead =FALSE;
	SetHqUsers(++dest_infos.aliveCount);
	return 0;
}

int CheckDest(int sd, struct sockaddr *dest, int curJys,
			int reqType, short *params, short paramsCount)
{
	LPDEST_INFO lpDestTmp;

	lpDestTmp =GetDest(dest);
	if(lpDestTmp ==NULL)
	{
		lpDestTmp =GetFirstDeadDest();
		if(!lpDestTmp) goto add_dest;
	}
	if(lpDestTmp->isDead)
		dest_infos.aliveCount++;
	ChangeDest(sd, lpDestTmp, dest, curJys, reqType,
			params, paramsCount);
	SetHqUsers(dest_infos.aliveCount);
	return 0;

add_dest:
	AddDest(sd, dest, curJys, reqType, params, paramsCount);
	SetHqUsers(dest_infos.aliveCount);

	return 0;
}

void HqDestSetDead(struct sockaddr *lpdest)
{
	LPDEST_INFO lpDestTmp;

	lpDestTmp =GetDest(lpdest);
	if(lpDestTmp)
	{
		lpDestTmp->isDead =TRUE;
		if(--dest_infos.aliveCount <0) dest_infos.aliveCount =0;
		SetHqUsers(dest_infos.aliveCount);
	}
}

void CheckDestEcho(int sd, struct sockaddr *dest)
{
	LPDEST_INFO lpDestTmp;

	lpDestTmp =GetDest(dest);
	if(lpDestTmp !=NULL)
		lpDestTmp->isEchoed =TRUE;
}

LPDEST_INFO GetDest(struct sockaddr *dest)
{
	int i;
	LPDEST_INFO lpDestTmp;
	
	//while(dest_infos.isUsing ==TRUE);
	//dest_infos.isUsing =TRUE;
	
	lpDestTmp =dest_infos.lpDestHead;

	for(i =0; idest)->sin_addr.s_addr
				==((struct sockaddr_in *)dest)->sin_addr.s_addr)
			break;
		lpDestTmp =lpDestTmp->lpNext;
	}
	////////////
	//dest_infos.isUsing =FALSE;
	
	return lpDestTmp;
}

LPDEST_INFO GetDestByUser(LPSTR userID)
{
	int i;
	LPDEST_INFO lpDestTmp;
	
	lpDestTmp =dest_infos.lpDestHead;

	for(i =0; iuserID, userID) ==0)
			break;
		lpDestTmp =lpDestTmp->lpNext;
	}
	////////////
	
	return lpDestTmp;
}

LPDEST_INFO HqDestSendClose(int sd, struct sockaddr *dest)
{
	int i;
	LPDEST_INFO lpDestTmp;
	
	lpDestTmp =dest_infos.lpDestHead;

	for(i =0; ilpNext;
		SendMsg(sd, "Server have closed!", &lpDestTmp->dest);
	}

	return lpDestTmp;
}

LPDEST_INFO GetFirstDeadDest(void)
{
	int i;
	LPDEST_INFO lpDestTmp;
	
	while(dest_infos.isUsing ==TRUE);
	dest_infos.isUsing =TRUE;
	
	lpDestTmp =dest_infos.lpDestHead;

	for(i =0; iisDead ==TRUE)
			break;
		lpDestTmp =lpDestTmp->lpNext;
	}
	dest_infos.isUsing =FALSE;
	return lpDestTmp;
}

void DelDeads(void)
{
	LPDEST_INFO lpDestPrev, lpDestNext, lpDestTmp;
	int i, count =0;
	if(dest_infos.aliveCount ==dest_infos.destCount)
		return;
	lpDestNext =lpDestTmp =dest_infos.lpDestHead;
	if(lpDestTmp ==NULL) return;

	while(dest_infos.isUsing ==TRUE);

	dest_infos.isUsing =TRUE;
	for(i =0; ilpNext;
		if(!lpDestTmp->isEchoed || lpDestTmp->isDead)
		{
			lpDestTmp->isDead =TRUE;
			if(--dest_infos.aliveCount <0) dest_infos.aliveCount =0;
			SetHqUsers(dest_infos.aliveCount);
			if(lpDestTmp ==dest_infos.lpDestHead)
				dest_infos.lpDestHead =lpDestNext;
			else lpDestPrev->lpNext =lpDestNext;
			free(lpDestTmp->params);
			lpDestTmp->paramsCount =0;
			if(lpDestTmp->lpCjss) free(lpDestTmp->lpCjss);
			lpDestTmp->lpCjss =NULL;
			if(lpDestTmp->lpGraph) free(lpDestTmp->lpGraph);
			lpDestTmp->lpGraph =NULL;
			if(lpDestTmp->lpZsGraph) free(lpDestTmp->lpZsGraph);
			lpDestTmp->lpZsGraph =NULL;
			free(lpDestTmp);
			count++;
		}
		else
			lpDestPrev =lpDestTmp;
		lpDestTmp =lpDestNext;
	}
	dest_infos.destCount -=count;
	dest_infos.isUsing =FALSE;

}

void FreeDest(void)
{
	LPDEST_INFO lpDestNext, lpDestTmp;
	int i;

	lpDestNext =lpDestTmp =dest_infos.lpDestHead;

	while(dest_infos.isUsing ==TRUE);

	dest_infos.isUsing =TRUE;
	for(i =0; ilpNext;
		if(lpDestTmp->params)
			free(lpDestTmp->params);
		if(lpDestTmp->lpCjss) free(lpDestTmp->lpCjss);
		free(lpDestTmp);
		lpDestTmp =lpDestNext;
	}

	dest_infos.destCount =0;
	dest_infos.isUsing =FALSE;
}

// can use WM_TIMER to run this function
long TF_ScanDest(void)
{
	int i;
	LPDEST_INFO lpDestNext;
	DP_MAIN DpMain[2];
	
	while(1)
	{
		lpDestNext=dest_infos.lpDestHead;
	
		if(run_cancelled) return 0;
		for(i =0; icurJys].fRunning ==FALSE)
				goto do_next;
			if(lpDestNext->isDead) goto do_next;
			if(lpDestNext->isUsing) goto do_next;
			//lpDestNext->isUsing =TRUE;
			switch(lpDestNext->reqType)
			{
			case REQ_HQ10:
				if(UDP_Server_Send_Hq10(lpDestNext)<0)
				{
					lpDestNext->isDead =TRUE;
					if(--dest_infos.aliveCount <0) dest_infos.aliveCount =0;
					SetHqUsers(dest_infos.aliveCount);
					goto do_next;
				}
				break;
			case REQ_GRA10:
				if(UDP_Server_Send_Gra10(lpDestNext)<0)
				{
					lpDestNext->isDead =TRUE;
					if(--dest_infos.aliveCount <0) dest_infos.aliveCount =0;
					SetHqUsers(dest_infos.aliveCount);
					goto do_next;
				}
				break;
			default: goto do_next;
			}
			if(!lpDestNext->isDead)
			{
				FillDpMain(&DpMain[0]);
				if(memcmp(&lpDestNext->DpData, &DpMain, sizeof(DpMain)))
				{
					if(UDP_Server_Send_Dp(&lpDestNext->dest, FALSE) <0)
					{
						lpDestNext->isDead =TRUE;
						if(--dest_infos.aliveCount <0) dest_infos.aliveCount =0;
						SetHqUsers(dest_infos.aliveCount);
					}
					else memcpy(&lpDestNext->DpData, &DpMain, sizeof(DpMain));
			
				}
			}
do_next:
			//lpDestNext->isUsing =FALSE;
			lpDestNext =lpDestNext->lpNext;
		}
		//HqResetChangedTimes();
		//DelDeads();
		Sleep(1000);
	}
	ExitThread(0);
	//CloseHandle(hThrdScanDest);
	//hThrdScanDest =0;
	return 0;
}

int CreateScanDestThread(void)
{
	LONG lThreadId;
	
	hThrdScanDest =CreateThread(NULL, 0,
		(LPTHREAD_START_ROUTINE)TF_ScanDest,
		NULL, CREATE_SUSPENDED, (LPDWORD)&lThreadId);
	if(!hThrdScanDest) return -1;
	SetThreadPriority(hThrdScanDest, THREAD_PRIORITY_NORMAL);
	
	ResumeThread(hThrdScanDest);
	
	return 0;
}

int FillDpMain(LPDP_MAIN lpDpMain)
{
	int jys;

	for(jys =0; jys<2; jys++)
	{
		lpDpMain[jys].zs =DpData[jys].zs[0];
		lpDpMain[jys].zd =DpData[jys].zd[0];
		lpDpMain[jys].cjzje =DpData[jys].cjzje;
		lpDpMain[jys].npbl =DpData[jys].npbl;
		lpDpMain[jys].cjss =DpData[jys].cjss;
		lpDpMain[jys].upCount =DpData[jys].upCount;
		lpDpMain[jys].downCount =DpData[jys].downCount;
		lpDpMain[jys].equalCount =DpData[jys].equalCount;
	}
	
	return 0;
}