NETWORK.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:20k
源码类别:
Windows编程
开发平台:
Visual C++
- /***********************************************************************
- File: Network.c
- Abstract:
- This is the network communications module for MazeLords. It contains functions
- to implement mailslots, as well as the various protocols and so-on required
- for communications.
- Contents:
- MemCRC() -- Generates a 'unique' LONG for different data structures
- SendNetMessage() -- Transmit a pre-made structure to other players
- MailWatchThread() -- Thread process to watch for new mail
- InitNetwork() -- Create mailslot, Send out ID message to network.
- ProcessNewMail() -- Process newly recieved data packets
- ************************************************************************/
- #include <windows.h>
- #include <mmsystem.h>
- #include "winmaze.h"
- #include "mazproto.h"
- #include "net.h"
- #include "crctable.h"
- /*=====================================================================
- Function: MemCRC()
- Inputs: Buffer & buffer length to CRC
- Outputs: Returns single Long corresponding to CRC for structure
- Abstract:
- The CRC should provide a unique ID for each player, provided ANY
- information in their data structures is unique. Each player is
- responsible for generating their ID & transmitting it to the other
- players.
- ======================================================================*/
- unsigned long MemCRC(
- LPSTR buffer,
- int bytes
- )
- {
- unsigned long crc = 0xFFFFFFFF;
- LPSTR p;
- for ( p = buffer; bytes > 0; bytes-- ) {
- crc = ( crc >> 8 ) ^ CRCtable[(unsigned char) ((unsigned char) crc ^ *p++ ) ];
- }
- return ( crc ^ 0xFFFFFFFF );
- }
- /*=====================================================================
- Function: SendNetMessage()
- Inputs: Source, destination, structure to send, packet type
- Outputs: Returns success/failure
- Abstract:
- SendNetMessage will send a message to all mazelords mailslots in the
- current domain. Note that this message is broadcast once. It is up
- to the individual recipients to decide whether it is addressed to them,
- or a general message (sent to -1).
- ======================================================================*/
- BOOL SendNetMessage(
- unsigned long ulSender,
- unsigned long ulDest,
- LPVOID lpStruct,
- DWORD dwPacketType
- )
- {
- BOOL bResult=TRUE;
- HANDLE hFile;
- DWORD dwScratch,dwLength;
- char cBuff[MAX_PACKET_SIZE];
- LPSTR lpStr;
- NetPacketType FAR *lpN;
- PlayerInfoType FAR *lppiInfo,FAR *lppiInfo2;
- PositionType FAR *lpptPos,FAR *lpptPos2;
- int FAR *iScore;
- IntoneType FAR *itIntone;
- if (!bNetworked) {
- return(TRUE);
- }
- lpN = (NetPacketType FAR *) cBuff;
- lpN->ulSender = (ulSender)? ulSender : ptSelf.ulID;
- lpN->ulDest = ulDest;
- lpN->dwPacketType = dwPacketType;
- dwLength = sizeof(NetPacketType);
- //
- // determine size, type of packet and fill out info accordingly.
- //
- lpStr = (LPSTR) &lpN->cData;
- switch(dwPacketType) {
- case NP_NEWPLAYER:
- lppiInfo = (PlayerInfoType FAR *) lpStr;
- lppiInfo2 = (PlayerInfoType FAR *) lpStruct;
- *lppiInfo = *lppiInfo2;
- dwLength += sizeof(PlayerInfoType);
- break;
- case NP_REQUESTIDENTITY:
- case NP_LEAVINGGAME:
- case NP_HITCONFIRM:
- break;
- case NP_MOVETO:
- case NP_SHOTFIRED:
- lpptPos = (PositionType FAR *) lpStr;
- lpptPos2 = (PositionType FAR *) lpStruct;
- *lpptPos = *lpptPos2;
- dwLength += sizeof(PositionType);
- break;
- case NP_SCORE:
- iScore = (int FAR *) lpStr;
- *iScore = ptSelf.iScore;
- dwLength += sizeof(int);
- break;
- case NP_INTONE:
- itIntone = (IntoneType FAR *) lpStr;
- *itIntone = *((IntoneType FAR *) lpStruct);
- dwLength += sizeof(IntoneType);
- dwLength -= (131 - itIntone->dwLen);
- break;
- default:
- MessageBox((HWND)NULL,GetStringRes(IDS_BADPCKTXMITFAIL),"SendNetMessage",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- break;
- }
- #ifdef WIN32
- hFile = CreateFile("\\*\mailslot\mazemslt",
- GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- bResult = (hFile != INVALID_HANDLE_VALUE);
- bResult = bResult &&
- WriteFile(hFile,cBuff,dwLength+1,&dwScratch,NULL);
- return(bResult && CloseHandle(hFile));
- #else // else it's any operating system except WIN32
- return(TRUE);
- #endif
- }
- /*=====================================================================
- Function: MailWatchThread()
- Inputs: Handle to mailslot to watch
- Outputs: none
- Abstract:
- This is a thread which is spawned. As soon as it sees a mail message
- is queued up, it sends a message to the main window notifying Maze
- Lords that new mail has been received. This is done 5 times a second.
- ======================================================================*/
- void MailWatchThread(
- HANDLE hMailSlot
- )
- {
- DWORD cbMaxMsg,cbNextMsg,cMsg,dwReadTimeout;
- #ifdef WIN32
- while(TRUE) {
- Sleep(200);
- if (GetMailslotInfo(hMailSlot,&cbMaxMsg,&cbNextMsg,&cMsg,&dwReadTimeout)) {
- if (cMsg > 0) {
- PostMessage(hWndMain,WM_COMMAND,IDT_NEWMAIL,0);
- }
- }
- }
- #endif
- //
- // We shouldn't ever get here.
- //
- return;
- }
- /*=====================================================================
- Function: InitNetwork()
- Inputs: none
- Outputs: returns success/failure
- Abstract:
- InitNetwork takes care of creating a mailslot for this user, and
- sending out a packet saying that we're joining the game.
- FALSE indicates that there was a fatal error starting the network.
- ======================================================================*/
- BOOL InitNetwork(
- void
- )
- {
- DWORD dwScratch;
- BOOL bRet;
- PlayerInfoType ptPlayScr;
- bRet = TRUE;
- //
- // initialize player list
- //
- ptPlayers.next = (PlayerType FAR *)NULL;
- if (!bNetworked) {
- hMailSlot = NULL;
- return(TRUE);
- }
- #ifdef WIN32
- hMailSlot = CreateMailslot("\\.\mailslot\mazemslt",0,0,NULL);
- if (hMailSlot == INVALID_HANDLE_VALUE) {
- MessageBox(NULL,GetStringRes(IDS_CREMSLOTFAIL),
- GetStringRes2(IDS_NETINIT), MB_ICONEXCLAMATION|MB_APPLMODAL);
- bRet = FALSE;
- }
- if (! CreateThread((LPSECURITY_ATTRIBUTES) NULL,
- 0,
- (LPTHREAD_START_ROUTINE)MailWatchThread,
- (LPVOID)hMailSlot,
- 0,&dwScratch)) {
- MessageBox(NULL,GetStringRes(IDS_CREMWATCHTHRFAIL),
- GetStringRes2(IDS_NETINIT), MB_ICONEXCLAMATION|MB_APPLMODAL);
- bRet = FALSE;
- }
- #endif
- ptPlayScr.ulID = ptSelf.ulID;
- ptPlayScr.dwPID = ptSelf.dwPID;
- lstrcpy(ptPlayScr.cUserName,ptSelf.cUserName);
- lstrcpy(ptPlayScr.cComputerName,ptSelf.cComputerName);
- ptPlayScr.ix = ptSelf.Pos.ix;
- ptPlayScr.iy = ptSelf.Pos.iy;
- ptPlayScr.bFacing = ptSelf.Pos.Facing;
- ptPlayScr.iScore = ptSelf.iScore;
- ptPlayScr.iPicNum = ptSelf.iPicNum;
- ptPlayScr.iGridNum = ptSelf.iGridNum;
- ptPlayScr.pGridLoc = ptSelf.pGridLoc;
- return(bRet&&SendNetMessage(0,0,(LPVOID) &ptPlayScr,NP_NEWPLAYER));
- }
- /*=====================================================================
- Function: ProcessNewMail()
- Inputs: none
- Outputs: none
- Abstract:
- ProcessNewMail is responsible for updating character positions, asking
- for more information, etc.
- ======================================================================*/
- void ProcessNewMail(
- void
- )
- {
- DWORD cbMaxMsg,cbNextMsg,cMsg,dwReadTimeout;
- NetPacketType FAR *NPkt;
- PlayerInfoType FAR *piPlayerPacket,piScratch;
- PlayerType FAR *ptTrav;
- PositionType FAR *ptPosPacket;
- BOOL bFound,bDrawMessageSent;
- int ix,iy;
- BYTE bSquare1, bSquare2,Facing;
- char cBuff[257],cNetMessBuff[400];
- int FAR *iScore;
- IntoneType FAR *itIntone;
- #ifdef WIN32
- GetMailslotInfo(hMailSlot,&cbMaxMsg,&cbNextMsg,&cMsg,&dwReadTimeout);
- bDrawMessageSent = FALSE;
- while (cMsg) {
- if (!ReadFile(hMailSlot,cNetMessBuff,cbNextMsg,&cbMaxMsg,(LPOVERLAPPED) NULL)) {
- MessageBox(NULL,GetStringRes(IDS_RDMSLOTFAIL),"ProcessNewMail",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
- NPkt = (NetPacketType FAR *) cNetMessBuff;
- //
- // Don't process the message if it's one of our own
- //
- if ((NPkt->ulSender != ptSelf.ulID)&&
- ((NPkt->ulDest == ptSelf.ulID)||(NPkt->ulDest == 0))
- ) {
- piPlayerPacket = (PlayerInfoType FAR *) &(NPkt->cData);
- ptPosPacket = (PositionType FAR *) &(NPkt->cData);
- iScore = (int FAR *) &(NPkt->cData);
- itIntone = (IntoneType FAR *) &(NPkt->cData);
- bFound = FALSE;
- ptTrav = &ptPlayers;
- while (ptTrav->next != NULL) {
- if (ptTrav->next->ulID == NPkt->ulSender) {
- bFound = TRUE;
- break;
- }
- ptTrav = ptTrav->next;
- }
- if ((!bFound)&&(NPkt->dwPacketType != NP_NEWPLAYER)) {
- if(!SendNetMessage(0,NPkt->ulSender,NULL,NP_REQUESTIDENTITY)) {
- MessageBox(NULL,GetStringRes(IDS_SNDPCKTFAIL),"ProcessNewMail",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
- }
- switch (NPkt->dwPacketType) {
- case (NP_NEWPLAYER):
- if (!bFound) {
- ptTrav->next = NewPlayer(piPlayerPacket->ulID,
- piPlayerPacket->dwPID,
- piPlayerPacket->cUserName,
- piPlayerPacket->cComputerName,
- piPlayerPacket->ix,
- piPlayerPacket->iy,
- piPlayerPacket->bFacing,
- piPlayerPacket->iScore,
- piPlayerPacket->iPicNum,
- piPlayerPacket->iGridNum,
- piPlayerPacket->pGridLoc.x,
- piPlayerPacket->pGridLoc.y,
- ptTrav->next);
- if (!AddPic(piPlayerPacket->iPicNum)) {
- ptTrav->next->iPicNum = PIC_DEFAULT;
- sprintf(cBuff, GetStringRes(IDS_FMT_BADPICNUM),
- piPlayerPacket->iPicNum,piPlayerPacket->cComputerName);
- PrintTextLine(cBuff);
- AddPic(PIC_DEFAULT);
- }
- //
- // After we add the user to our own database,
- // let him know we exist.
- //
- sprintf(cBuff,GetStringRes(IDS_FMT_JOIN),ptTrav->next->cUserName);
- PrintTextLine(cBuff);
- piScratch.ulID = ptSelf.ulID;
- piScratch.dwPID = ptSelf.dwPID;
- strcpy(piScratch.cUserName,ptSelf.cUserName);
- strcpy(piScratch.cComputerName,ptSelf.cComputerName);
- piScratch.ix = ptSelf.Pos.ix;
- piScratch.iy = ptSelf.Pos.iy;
- piScratch.bFacing = ptSelf.Pos.Facing;
- piScratch.iScore = ptSelf.iScore;
- piScratch.iPicNum = ptSelf.iPicNum;
- piScratch.iGridNum = ptSelf.iGridNum;
- piScratch.pGridLoc = ptSelf.pGridLoc;
- if (!SendNetMessage(0,NPkt->ulSender,&piScratch,NP_NEWPLAYER)) {
- MessageBox(NULL,GetStringRes(IDS_SNDPCKTFAIL),"ProcessNewMail",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
- //
- // Finally, do a redraw to make sure if he's in
- // line of sight we see him. */
- //
- PostMessage(hWndMaze,WM_COMMAND,IDM_DRAWPLAYERS,0);
- PostMessage(hWndScore,WM_COMMAND,WC_ADDSCORE,ptTrav->next->ulID);
- }
- break;
- case (NP_REQUESTIDENTITY):
- piScratch.ulID = ptSelf.ulID;
- piScratch.dwPID = ptSelf.dwPID;
- strcpy(piScratch.cUserName,ptSelf.cUserName);
- strcpy(piScratch.cComputerName,ptSelf.cComputerName);
- piScratch.ix = ptSelf.Pos.ix;
- piScratch.iy = ptSelf.Pos.iy;
- piScratch.bFacing = ptSelf.Pos.Facing;
- piScratch.iScore = ptSelf.iScore;
- piScratch.iPicNum = ptSelf.iPicNum;
- piScratch.iGridNum = ptSelf.iGridNum;
- piScratch.pGridLoc = ptSelf.pGridLoc;
- if (!SendNetMessage(0,NPkt->ulSender,&piScratch,NP_NEWPLAYER)) {
- MessageBox(NULL,GetStringRes(IDS_SNDPCKTFAIL),"ProcessNewMail",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
- break;
- case (NP_MOVETO):
- if (bFound) {
- ptTrav->next->Pos = *ptPosPacket;
- if (ptTrav->next->Drawn) {
- if (!bBitmapDraw) {
- InvalidateRect(hWndMaze,&ptTrav->next->rDrawn,TRUE);
- }
- //
- //BUGBUG -- drawing problem for bitmaps
- //
- ptTrav->next->Drawn=FALSE;
- }
- else {
- if (!bDrawMessageSent) {
- PostMessage(hWndMaze,WM_COMMAND,IDM_DRAWPLAYERS,0);
- bDrawMessageSent = TRUE;
- }
- }
- PostMessage(hWndScore,WM_COMMAND,WC_UPDATEDIRECTION,ptTrav->next->ulID);
- }
- break;
- case (NP_SHOTFIRED):
- if (bFound) {
- PlaySound("othrlasr.wav",NULL,SND_FILENAME|SND_ASYNC);
- //
- // if the shot was fired in the same 'x' or 'y'
- // plane, we may have been hit!
- //
- if ((ptPosPacket->ix == ptSelf.Pos.ix)||
- (ptPosPacket->iy == ptSelf.Pos.iy)
- ) {
- ix = ptPosPacket->ix;
- iy = ptPosPacket->iy;
- Facing = ptPosPacket->Facing;
- bSquare2 = bMaze[ix][iy];
- do {
- //
- // if we're hit, handle it!
- //
- if ((!InSanctuary(&ptSelf.Pos))&&(ptSelf.Pos.ix == ix)&&(ptSelf.Pos.iy == iy)) {
- if (!SendNetMessage(0,NPkt->ulSender,NULL,NP_HITCONFIRM)) {
- MessageBox(NULL,GetStringRes(IDS_SNDPCKTFAIL),"MazeWndProc",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
- sprintf(cBuff,GetStringRes(IDS_FMT_ZAPPEDYOU),ptTrav->next->cUserName);
- PrintTextLine(cBuff);
- KillSelf();
- break;
- }
- //
- // otherwise, keep checking.
- //
- bSquare1 = bSquare2;
- bSquare2 = bMaze[ix = ADJ_X(ix,Facing)][iy = ADJ_Y(iy,Facing)];
- } while (!((bSquare1 & Facing)||(bSquare2 & BACK_TO_ABS(Facing))));
- }
- }
- break;
- case (NP_LEAVINGGAME):
- //
- // ***BUGBUG*** Might cause problems if character leaving is on screen
- //
- if (bFound) {
- sprintf(cBuff,GetStringRes(IDS_FMT_LEFT),ptTrav->next->cUserName);
- PrintTextLine(cBuff);
- PostMessage(hWndScore,WM_COMMAND,WC_DELETESCORE,ptTrav->next->ulID);
- ptTrav->next = DeletePlayer(ptTrav->next);
- PostMessage(hWndMaze,WM_COMMAND,IDM_DRAWPLAYERS,0);
- }
- break;
- case (NP_HITCONFIRM):
- PlaySound("squish.wav",NULL,SND_FILENAME|SND_ASYNC);
- if (bFound) {
- FadePic(ptTrav->next->iPicNum,
- ptTrav->next->Pos.Facing,
- hMazeDC,
- &ptTrav->next->rFrom,
- &ptTrav->next->rDrawn);
- sprintf(cBuff,GetStringRes(IDS_FMT_HIT),ptTrav->next->cUserName);
- PrintTextLine(cBuff);
- }
- ptSelf.iScore += 50;
- iPlayersKilled++;
- SendNetMessage(0,0,NULL,NP_SCORE);
- PostMessage(hWndScore,WM_COMMAND,WC_UPDATESCORE,ptSelf.ulID);
- break;
- case (NP_SCORE):
- if (bFound) {
- ptTrav->next->iScore = *iScore;
- PostMessage(hWndScore,WM_COMMAND,WC_UPDATESCORE,ptTrav->next->ulID);
- }
- break;
- case NP_INTONE:
- if (bFound) {
- ix = ptSelf.Pos.ix - itIntone->Pos.ix;
- iy = ptSelf.Pos.iy - itIntone->Pos.iy;
- if ((ix*ix + iy*iy) <= (itIntone->iLoudness * itIntone->iLoudness)) {
- sprintf(cBuff,"[%s] - "%s"",ptTrav->next->cUserName,
- itIntone->cBuff);
- PrintTextLine(cBuff);
- }
- }
- break;
- default:
- MessageBox(NULL,GetStringRes(IDS_BADMSG),"ProcessNewMail",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- break;
- }
- }
- GetMailslotInfo(hMailSlot,&cbMaxMsg,&cbNextMsg,&cMsg,&dwReadTimeout);
- }
- #endif // end if WIN32. This whole function is not present for WIN16.
- return;
- }