Message.cpp
上传用户:royluo
上传日期:2007-01-05
资源大小:1584k
文件大小:22k
源码类别:

游戏

开发平台:

Visual C++

  1. /*****************************************************************************
  2. *                                                                             
  3. *   Message.cpp                                                            
  4. *                                                                             
  5. *   Electrical Engineering Faculty - Software Lab                             
  6. *   Spring semester 1998                                                      
  7. *                                                                             
  8. *   Tanks game                                                                
  9. *                                                                             
  10. *   Module description: Messages are send between the game threads (in process)
  11. *                       and over the network between the host and players.
  12. *                       We use pool allocation techniques to make message 
  13. *                       allocation fast and bit fields to compact the size of 
  14. *                       messages when send over the net.
  15. *                                                                             
  16. *   Authors: Eran Yariv - 28484475                                           
  17. *            Moshe Zur  - 24070856                                           
  18. *                                                                            
  19. *                                                                            
  20. *   Date: 23/09/98                                                           
  21. *                                                                            
  22. ******************************************************************************/
  23. #include "stdafx.h"
  24. #include "Message.h"
  25. #include "Tanks.h"
  26. #pragma pack (push)
  27. #pragma pack (1)
  28. CPool<CMessage> CMessage::m_Pool;       // The message pool. We overload the new and
  29.                                         // delete methods to use the pools fast allocation
  30.                                         // and deallocation methods.
  31. #define VAR_LEN                         0xFF     // Variable message length
  32. #define TNK_CHK_SUM_TO_TANK_ID(pb)      (BYTE(( ((PBYTE(pb))[2]) >> 2) & 0x03))
  33. #define MSG_HEADER_SIZE                 5   // Msg type (1 Byte) + Msg time (DWORD)
  34. static BYTE MsgSizeArr[] =              // Messages size look up table:
  35. {
  36.     MSG_HEADER_SIZE + sizeof (BonusParamTag),           // ADD_BONUS 
  37.                                                         // (See BonusParamTag for description)
  38.     MSG_HEADER_SIZE + sizeof (TankParamTag),            // ADD_TANK  
  39.                                                         // (See TankParamTag for description)
  40.     MSG_HEADER_SIZE + sizeof (BoardParamTag),           // ADD_BOARD 
  41.                                                         // (See BoardParamTag for description)
  42.     MSG_HEADER_SIZE + sizeof (BomberParamTag),          // ADD_BOMBER 
  43.                                                         // (See BomberParamTag for description)
  44.     MSG_HEADER_SIZE + sizeof (TankRemoveParamTag),      // REMOVE_TANK 
  45.                                                         // (See TankRemoveParamTag for description)
  46.     MSG_HEADER_SIZE + sizeof (ManouverSetParamTag),     // MANOUVER_SET 
  47.                                                         // (See ManouverSetParamTag for description)
  48.     MSG_HEADER_SIZE + sizeof (TankStatusParamTag),      // SET_TANK_STATUS 
  49.                                                         // (See TankStatusParamTag for description)
  50.     MSG_HEADER_SIZE + sizeof (TankPosParamTag),         // SET_TANK_POS
  51.                                                         // (See TankPosParamTag for description)
  52.     MSG_HEADER_SIZE + sizeof (TankZombieParamTag),      // SET_TANK_ZOMBIE
  53.                                                         // (See TankZombieParamTag for description)
  54.     MSG_HEADER_SIZE + sizeof (TankRequestParamTag),     // REQUEST_TANK
  55.                                                         // (See TankRequestParamTag for description)
  56.     VAR_LEN,                                            // CHECK_SUM
  57.                                                         // (See SingleTankChkSumType for description)
  58.     VAR_LEN                                             // CHAT
  59. };
  60. BYTE         * CMessage::m_MsgSizeArr = MsgSizeArr;
  61. TIMER_CLASS  * CMessage::m_pTimer = NULL;
  62. /*------------------------------------------------------------------------------
  63.   Function: Constructor.
  64.   Purpose:  Constructor for messages created internally (not from network)
  65.   Input:    type: Type of message to be constructed.
  66.             data: Data of message to be constructed.
  67.             typ:  Flag to indicate if message contains our local game time
  68.                   (internal message between threads) or the host game time
  69.                   (external message sent over the net).
  70. ------------------------------------------------------------------------------*/
  71. CMessage::CMessage (MessageType type, 
  72.                     union MessageData& data, 
  73.                     GameMessageType typ) : 
  74.     m_Type (type), 
  75.     m_UnionData (data)
  76. {   
  77.     if (NULL == m_pTimer)
  78.         m_pTimer = &(TANKS_APP->m_gTimer);
  79.     memcpy (&m_UnionData, &data, sizeof(union MessageData));
  80.     if (PLAYER_MSG == typ)
  81.     {   // Message created internally (not from network) and is directed out.
  82.         // This only happens for clients.
  83.         // Convert to server's time (game time)
  84.         m_dwMsgTime = m_pTimer->GetRemoteTime ();
  85.     }
  86.     else 
  87.         // Just store local time as message time:
  88.         m_dwMsgTime = m_pTimer->GetLocalTime();
  89. }
  90. /*------------------------------------------------------------------------------
  91.   Function: Constructor.
  92.   Purpose:  Constructor for messages arriving from network (not created internally)
  93.   Input:    pData: Pointer to data buffer.
  94.             bDataSize:  Size of data buffer.
  95.             typ: Flag indicating if message time is global (host) or local 
  96.                  (any player).
  97. ------------------------------------------------------------------------------*/
  98. CMessage::CMessage (PBYTE pData, BYTE bDataSize, GameMessageType typ)
  99. {
  100.     if (NULL == m_pTimer)
  101.         m_pTimer = &(TANKS_APP->m_gTimer);
  102.         // Get message ID
  103.     BYTE bType = BYTE((pData[0]) & 0x000F);
  104.         // Make sure the message has a valid type
  105.     ASSERT (bType < sizeof (MsgSizeArr) / sizeof(MsgSizeArr[0]));
  106.         // Make sure the data fits the size according to its type
  107.     ASSERT ((VAR_LEN == m_MsgSizeArr[bType]) ||     // Variable length or (ignored)
  108.             (bDataSize == m_MsgSizeArr[bType]));    // exact length
  109.         // Message type ok - store it.
  110.     m_Type = MessageType(bType);
  111.     pData++;
  112.         // Read time from message
  113.     PDWORD pTime = PDWORD(pData);
  114.     if (PLAYER_MSG == typ)
  115.     { // Requested by player (coming from server), convert to local time
  116.         m_dwMsgTime = m_pTimer->GetLocalTime (*pTime);
  117.     }
  118.     else
  119.     { // Requested by server (coming from a client to server), already in server's time
  120.         m_dwMsgTime = *pTime;
  121.     }
  122.     pData += sizeof(DWORD);
  123.         // Handle decoding of incoming message according to type
  124.     switch (m_Type)
  125.     {   
  126.         case ADD_BONUS:                 // Server => Client
  127.             DecodeAddBonus (pData);     
  128.             break;
  129.         case ADD_TANK:                  // Server => Client
  130.             DecodeAddTank (pData);
  131.             break;
  132.         case ADD_BOARD:                 // Server => Client
  133.             DecodeAddBoard (pData);
  134.             break;
  135.         case ADD_BOMBER:                // Server => Client
  136.             DecodeAddBomber (pData);
  137.             break;
  138.         case REMOVE_TANK:               // Server => Client
  139.             DecodeRemoveTank (pData);
  140.             break;
  141.         case MANOUVER_SET:              // Server <=> Client
  142.             DecodeManouverSet (pData);
  143.             break;
  144.         case REQUEST_TANK:              // Client => Server
  145.             DecodeRequestTank (pData);
  146.             break;
  147.         case CHECK_SUM:                 // Client => Server;
  148.             DecodeCheckSum (pData);
  149.             break;
  150.         case SET_TANK_STATUS:            // Server => Client
  151.             DecodeSetTankStatus (pData);
  152.             break;
  153.         case SET_TANK_POS:              // Server => Client
  154.             DecodeSetTankPos (pData);
  155.             break;
  156.         case SET_TANK_ZOMBIE:              // Server => Client
  157.             DecodeSetTankZombie (pData);
  158.             break;
  159.         case CHAT:
  160.             DecodeChat(pData);
  161.             break;
  162.         default:
  163.             ASSERT (FALSE);
  164.             break;
  165.     }
  166.     UNREFERENCED_PARAMETER(bDataSize);
  167. }
  168. /*------------------------------------------------------------------------------
  169.   Function: GetBuffer
  170.   Purpose:  Spools the message contents to buffer, minimizing buffer size by 
  171.             using bit fields to store the message contents.
  172.   Input:    pRes: Pointer to buffer.
  173.   Output:   Return the buffer length.
  174.   Remarks:  Each type of message has an encoding method to convert data to
  175.             compact structure w/o loosing information.
  176. ------------------------------------------------------------------------------*/
  177. DWORD        
  178. CMessage::GetBuffer (PBYTE pRes)
  179. {
  180.         // Store the type
  181.     pRes[0] = BYTE(m_Type);
  182.     pRes++;
  183.         // Store the remote time
  184.     *((PDWORD)pRes) = m_dwMsgTime;
  185.     pRes += sizeof (DWORD);
  186.         // Handle encoding of message according to type
  187.     switch (m_Type)
  188.     {   
  189.         case REQUEST_TANK:          // Client => Server
  190.             return EncodeRequestTank (pRes);
  191.         case ADD_BONUS:             // Server => Client
  192.             return EncodeAddBonus (pRes);
  193.         case ADD_TANK:              // Server => Client
  194.             return EncodeAddTank (pRes);
  195.         case ADD_BOARD:             // Server => Client
  196.             return EncodeAddBoard (pRes);
  197.         case ADD_BOMBER:            // Server => Client
  198.             return EncodeAddBomber (pRes);
  199.         case REMOVE_TANK:           // Server => Client
  200.             return EncodeRemoveTank (pRes);
  201.         case MANOUVER_SET:          // Server <=> Client
  202.             return EncodeManouverSet (pRes);
  203.         case CHECK_SUM:             // Client => Server
  204.             return EncodeCheckSum (pRes);
  205.         case SET_TANK_STATUS:        // Server => Client
  206.             return EncodeSetTankStatus (pRes);
  207.         case SET_TANK_POS:          // Server => Client
  208.             return EncodeSetTankPos (pRes);
  209.         case SET_TANK_ZOMBIE:       // Server => Client
  210.             return EncodeSetTankZombie (pRes);
  211.         case CHAT:
  212.             return EncodeChat(pRes);
  213.         default:
  214.             ASSERT (FALSE);
  215.             return 0;
  216.     }
  217. }
  218. // Encoding & decoding functions:
  219. // ------------------------------
  220. DWORD            
  221. CMessage::EncodeAddBomber (PBYTE pData) 
  222. {
  223.     // Validate data to encode
  224.     ASSERT (m_UnionData.BomberParam.Direction < 24);
  225.     *((BomberParamTag *)pData) = m_UnionData.BomberParam;
  226.     return m_MsgSizeArr[ADD_BOMBER];
  227. }
  228. void            
  229. CMessage::DecodeAddBomber (PBYTE pData)
  230. {
  231.     m_UnionData.BomberParam = *((BomberParamTag *)pData);
  232.     ASSERT (m_UnionData.BomberParam.Direction < 24);
  233. }
  234. DWORD            
  235. CMessage::EncodeRequestTank (PBYTE pData) const
  236. {
  237.     // Validate data to encode
  238.     ASSERT (m_UnionData.TankRequestParam.bID < 4);
  239.     *pData = m_UnionData.TankRequestParam.bID;
  240.     return m_MsgSizeArr[REQUEST_TANK];
  241. }
  242. void            
  243. CMessage::DecodeRequestTank (PBYTE pData)
  244. {
  245.     m_UnionData.TankRequestParam.bID = *pData;
  246.     ASSERT (m_UnionData.TankRequestParam.bID < 4);
  247. }
  248. DWORD            
  249. CMessage::EncodeManouverSet (PBYTE pData) const
  250. {
  251.     // Validate data to encode
  252.     ASSERT (m_UnionData.ManouverSetParam.Direction < 24);
  253.     *((ManouverSetParamTag *)pData) = m_UnionData.ManouverSetParam;
  254.     return m_MsgSizeArr[MANOUVER_SET];
  255. }
  256. void            
  257. CMessage::DecodeManouverSet (PBYTE pData)
  258. {
  259.     m_UnionData.ManouverSetParam = *((ManouverSetParamTag *)pData);
  260.     ASSERT (m_UnionData.ManouverSetParam.Direction < 24);
  261. }
  262. DWORD            
  263. CMessage::EncodeAddBonus (PBYTE pData) const
  264. {
  265.     ASSERT (m_UnionData.BonusParam.XPos < 512);
  266.     ASSERT (m_UnionData.BonusParam.YPos < 512);
  267.     ASSERT (BonusType(m_UnionData.BonusParam.Type) < NUM_BONUSES);
  268.     *((BonusParamTag *)pData) = m_UnionData.BonusParam;
  269.     return m_MsgSizeArr[ADD_BONUS];
  270. }
  271. void            
  272. CMessage::DecodeAddBonus (PBYTE pData)
  273. {
  274.     m_UnionData.BonusParam = *((BonusParamTag *)pData);
  275.     ASSERT (BonusType(m_UnionData.BonusParam.Type) < NUM_BONUSES);
  276. }
  277. DWORD            
  278. CMessage::EncodeAddTank (PBYTE pData) const
  279. {
  280.     ASSERT (m_UnionData.TankParam.ShieldLevel < 101);
  281.     ASSERT (m_UnionData.TankParam.Direction < 24);
  282.     *((TankParamTag*)pData) = m_UnionData.TankParam;
  283.     return m_MsgSizeArr[ADD_TANK];
  284. }
  285. void            
  286. CMessage::DecodeAddTank (PBYTE pData)
  287. {
  288.     m_UnionData.TankParam = *((TankParamTag*)pData);
  289.     ASSERT (m_UnionData.TankParam.ShieldLevel < 101);
  290.     ASSERT (m_UnionData.TankParam.Direction < 24);
  291. }
  292. DWORD            
  293. CMessage::EncodeAddBoard (PBYTE pData) const
  294. {
  295.     ASSERT (m_UnionData.BoardParam.Seed < 0xFFFF);
  296.     ASSERT (m_UnionData.BoardParam.Complexity < 0x001F);
  297.     *((BoardParamTag *)pData) = m_UnionData.BoardParam;
  298.     return m_MsgSizeArr[ADD_BOARD];
  299. }
  300. void            
  301. CMessage::DecodeAddBoard (PBYTE pData)
  302. {
  303.     m_UnionData.BoardParam = *((BoardParamTag *)pData);
  304. }
  305. DWORD            
  306. CMessage::EncodeRemoveTank (PBYTE pData) const
  307. {
  308.     *((TankRemoveParamTag *)pData) = m_UnionData.TankRemoveParam;
  309.     return m_MsgSizeArr[REMOVE_TANK];
  310. }
  311. void            
  312. CMessage::DecodeRemoveTank (PBYTE pData)
  313. {
  314.     m_UnionData.TankRemoveParam = *((TankRemoveParamTag *)pData);
  315. }
  316. DWORD           
  317. CMessage::EncodeSetTankStatus (PBYTE pBuffer) const
  318. {
  319.     *(TankStatusParamTag*)pBuffer = m_UnionData.TankStatusParam;
  320.     return m_MsgSizeArr[SET_TANK_STATUS];
  321. }
  322. void
  323. CMessage::DecodeSetTankStatus (PBYTE pBuffer)
  324. {
  325.     m_UnionData.TankStatusParam = *((TankStatusParamTag *)pBuffer);
  326. }
  327. DWORD
  328. CMessage::EncodeSetTankPos (PBYTE pBuffer) const
  329. {
  330.     *(TankPosParamTag*)pBuffer = m_UnionData.TankPosParam;
  331.     return m_MsgSizeArr[SET_TANK_POS];
  332. }
  333. void
  334. CMessage::DecodeSetTankPos (PBYTE pBuffer)
  335. {
  336.     m_UnionData.TankPosParam = *(TankPosParamTag*)pBuffer;
  337. }
  338. DWORD
  339. CMessage::EncodeSetTankZombie (PBYTE pBuffer) const
  340. {
  341.     *(TankZombieParamTag*)pBuffer = m_UnionData.TankZombieParam;
  342.     return m_MsgSizeArr[SET_TANK_ZOMBIE];
  343. }
  344. void
  345. CMessage::DecodeSetTankZombie (PBYTE pBuffer)
  346. {
  347.     m_UnionData.TankZombieParam = *(TankZombieParamTag*)pBuffer;
  348. }
  349. DWORD            
  350. CMessage::EncodeCheckSum (PBYTE pData) const
  351. {
  352.     ASSERT (m_UnionData.CheckSumParam.NumberOfTanks <= 4);
  353.     ASSERT ((m_UnionData.CheckSumParam.ActiveBonusType >= BONUS_NONE) &&
  354.             (m_UnionData.CheckSumParam.ActiveBonusType < NUM_BONUSES));
  355.     PBYTE pb = pData;
  356.     // First, do fixed part:
  357.     FixedSizeChkSumType *p = (FixedSizeChkSumType *)pb;
  358.     p->Header.NumberOfTanks     = m_UnionData.CheckSumParam.NumberOfTanks;
  359.     p->Header.DeadHostReport    = BYTE(m_UnionData.CheckSumParam.DeadHostReport ? 1 : 0);
  360.     p->Header.ActiveBonusType   = BYTE(m_UnionData.CheckSumParam.ActiveBonusType);
  361.     p->Header.XPos              = m_UnionData.CheckSumParam.XPos;
  362.     p->Header.YPos              = m_UnionData.CheckSumParam.YPos;
  363.         // Encode sector mines checksums:
  364.     int sect = 0;
  365.     for (int i=0; i<8; i++)
  366.     {
  367.         p->MinesSectorsChkSum[i].LoNibble = BYTE((m_UnionData.CheckSumParam.MinesSectorsChkSum[sect++]) & 0x0F);
  368.         p->MinesSectorsChkSum[i].HiNibble = BYTE((m_UnionData.CheckSumParam.MinesSectorsChkSum[sect++]) & 0x0F);
  369.     }
  370.     // Encode tanks - variable part:
  371.     pb += sizeof (FixedSizeChkSumType);
  372.     for (i=0; i<4; i++)
  373.         if (m_UnionData.CheckSumParam.TanksChkSums[i].TankExists)
  374.         {   // i'th tank exists
  375.             // Tank's encoding includes tank's ID
  376.             SingleTankChkSumType *p = (SingleTankChkSumType *)pb;
  377.             p->TankID   = i;
  378.             p->Zombie   = m_UnionData.CheckSumParam.TanksChkSums[i].Zombie;
  379.             p->Shells   = m_UnionData.CheckSumParam.TanksChkSums[i].Shells;
  380.             p->Bullets  = m_UnionData.CheckSumParam.TanksChkSums[i].Bullets;
  381.             p->Mines    = m_UnionData.CheckSumParam.TanksChkSums[i].Mines;
  382.             p->FastFire = m_UnionData.CheckSumParam.TanksChkSums[i].FastFire;
  383.             pb += sizeof (SingleTankChkSumType);
  384.         }
  385.     // Return true (varaible) message size    
  386.     DWORD dwMsgSize = sizeof (FixedSizeChkSumType) + 
  387.                       m_UnionData.CheckSumParam.NumberOfTanks * sizeof (SingleTankChkSumType);
  388.     ASSERT (pb == pData+dwMsgSize);
  389.     return dwMsgSize + 5;   // Including message header
  390. }
  391. void            
  392. CMessage::DecodeCheckSum (PBYTE pData)
  393. {
  394.     FixedSizeChkSumType *p = (FixedSizeChkSumType *)pData;
  395.     m_UnionData.CheckSumParam.NumberOfTanks     = p->Header.NumberOfTanks;
  396.     m_UnionData.CheckSumParam.DeadHostReport    = p->Header.DeadHostReport;
  397.     m_UnionData.CheckSumParam.ActiveBonusType   = BonusType(p->Header.ActiveBonusType);
  398.     m_UnionData.CheckSumParam.XPos = p->Header.XPos;
  399.     m_UnionData.CheckSumParam.YPos = p->Header.YPos;
  400.         // Decode sector mines checksums:
  401.     int sect = 0;
  402.     for (int i=0; i<8; i++)
  403.     {
  404.         m_UnionData.CheckSumParam.MinesSectorsChkSum[sect++] = p->MinesSectorsChkSum[i].LoNibble;
  405.         m_UnionData.CheckSumParam.MinesSectorsChkSum[sect++] = p->MinesSectorsChkSum[i].HiNibble;
  406.     }
  407.     ASSERT (m_UnionData.CheckSumParam.NumberOfTanks <= 4);
  408.     ASSERT ((m_UnionData.CheckSumParam.ActiveBonusType >= BONUS_NONE) &&
  409.             (m_UnionData.CheckSumParam.ActiveBonusType < NUM_BONUSES));
  410.     // Decode tanks - variable part:
  411.     // Clear all tanks data
  412.     memset (m_UnionData.CheckSumParam.TanksChkSums,
  413.             0,
  414.             sizeof (CheckSumParamTag::TankCheckSumParamTag) * MAX_TANKS);
  415.     pData += sizeof (FixedSizeChkSumType);
  416.     for (i=0; i<m_UnionData.CheckSumParam.NumberOfTanks; i++)
  417.     {
  418.         SingleTankChkSumType *p = (SingleTankChkSumType *)pData;
  419.         BYTE bTankID = BYTE(p->TankID);  // Get tank ID
  420.         ASSERT (bTankID < 4);
  421.         m_UnionData.CheckSumParam.TanksChkSums[bTankID].TankExists  = TRUE;
  422.         m_UnionData.CheckSumParam.TanksChkSums[bTankID].Zombie      = p->Zombie;
  423.         m_UnionData.CheckSumParam.TanksChkSums[bTankID].Shells      = WORD(p->Shells);
  424.         m_UnionData.CheckSumParam.TanksChkSums[bTankID].Bullets     = WORD(p->Bullets);
  425.         m_UnionData.CheckSumParam.TanksChkSums[bTankID].Mines       = WORD(p->Mines);
  426.         m_UnionData.CheckSumParam.TanksChkSums[bTankID].FastFire    = p->FastFire;
  427.         pData += sizeof (SingleTankChkSumType);
  428.     }
  429. }
  430. DWORD
  431. CMessage::EncodeChat (PBYTE pData) const
  432. {
  433.     *pData++ = m_UnionData.ChatParam.TankID;
  434.     PDWORD pdw = (PDWORD)pData;
  435.     *pdw++ = m_UnionData.ChatParam.idFrom;
  436.     pData = (PBYTE)pdw;
  437.     strcpy ((char *)pData, m_UnionData.ChatParam.Msg);
  438.     return DWORD(sizeof (m_UnionData.ChatParam) -           // Entire message
  439.                  sizeof (m_UnionData.ChatParam.Msg) +       // Leave const size
  440.                  strlen(m_UnionData.ChatParam.Msg) + 1 +    // Variable string 
  441.                  MSG_HEADER_SIZE);                          // Msg header
  442. }
  443.  
  444. void
  445. CMessage::DecodeChat (PBYTE pData)
  446. {
  447.     m_UnionData.ChatParam.TankID = *pData++;
  448.     m_UnionData.ChatParam.idFrom = *((PDWORD)(pData));
  449.     pData+=sizeof(DWORD);
  450.     // Assert msg length :
  451.     int len = strlen ((char *)pData);
  452.     ASSERT (len <= MAX_CHAT_MSG_LEN);
  453.     if (len > MAX_CHAT_MSG_LEN) 
  454.     {   // Chop string at last available char:
  455.         pData[MAX_CHAT_MSG_LEN] = '';
  456.         len = MAX_CHAT_MSG_LEN;
  457.     }
  458.     strcpy (m_UnionData.ChatParam.Msg, (char *)pData);
  459. }
  460. /* Special case - static mines per sector encoding / decoding functions : */
  461. DWORD 
  462. CMessage::EncodeSectorMines (PBYTE pData, int iSector, DWORD dwMinesFound, DWORD *pAllMinesInSector)
  463. {
  464.     pData[0] = BYTE(iSector);
  465.     pData[1] = BYTE(dwMinesFound);
  466.     DWORD dwDataSize = dwMinesFound * sizeof (DWORD);
  467.     memcpy (&pData[2], pAllMinesInSector, dwDataSize);
  468.     return dwDataSize + 2;
  469. }
  470. DWORD 
  471. CMessage::DecodeSectorMines (PBYTE pData, DWORD dwBufferSize, int &iSector, DWORD *pAllMinesInSector)
  472. {
  473.     ASSERT (dwBufferSize >= 2);
  474.     iSector = int(pData[0]);
  475.     DWORD dwMinesFound = DWORD(pData[1]);
  476.     DWORD dwDataSize = dwMinesFound * sizeof (DWORD);
  477.     ASSERT (dwBufferSize == dwDataSize + 2);
  478.     memcpy (pAllMinesInSector, &pData[2], dwDataSize);
  479.     return dwMinesFound;
  480.     UNREFERENCED_PARAMETER(dwBufferSize);
  481. }
  482. /* End of special case - static mines per sector encoding / decoding functions */
  483. #ifdef NET_MON_GAME
  484. char *
  485. CMessage::GetName()
  486. {   // Get message name
  487.     return CMessage::GetName (BYTE(m_Type));
  488. }
  489. char *
  490. CMessage::GetName(BYTE bID)
  491. {   // Get message name (static)
  492.     switch (bID)
  493.     {
  494.         case ADD_BONUS:
  495.             return "ADD_BONUS";
  496.         case ADD_TANK:
  497.             return "ADD_TANK";
  498.         case ADD_BOARD:
  499.             return "ADD_BOARD";
  500.         case ADD_BOMBER:
  501.             return "ADD_BOMBER";
  502.         case REMOVE_TANK:
  503.             return "REMOVE_TANK";
  504.         case MANOUVER_SET:
  505.             return "MANOUVER_SET";
  506.         case SET_TANK_STATUS:
  507.             return "SET_TANK_STATUS";
  508.         case SET_TANK_POS:
  509.             return "SET_TANK_POS";
  510.         case REQUEST_TANK:
  511.             return "REQUEST_TANK";
  512.         case CHECK_SUM:
  513.             return "CHECK_SUM";
  514.         case ADD_OBJECT:
  515.             return "ADD_OBJECT";
  516.         case ADD_SHELL:
  517.             return "ADD_SHELL";
  518.         case ADD_BULLET:
  519.             return "ADD_BULLET";
  520.         case ADD_GAME_OVER:
  521.             return "ADD_GAME_OVER";
  522.         case 0xff:
  523.             return "PING";
  524.         default:
  525.             return "unknown";
  526.     }
  527. }
  528. #endif  NET_MON_GAME
  529. #pragma pack (pop)