- Main Page
- Classes
- Files

- File List
- File Members

# E:/uas2/Server/Client.h

Go to the documentation of this file.

    00001 /*
    00002 * This file is part of UAS2.
    00003 *
    00004 * UAS2 is free software; you can redistribute it and/or modify
    00005 * it under the terms of the GNU General Public License as published by
    00006 * the Free Software Foundation; either version 2 of the License, or
    00007 * (at your option) any later version.
    00008 *
    00009 * UAS2 is distributed in the hope that it will be useful,
    00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00012 * GNU General Public License for more details.
    00013
    00014 * You should have received a copy of the GNU General Public License
    00015 * along with UASv1; if not, write to the Free Software
    00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00017 */
    00018
    00023 #ifndef __CLIENT_H
    00024 #define __CLIENT_H
    00025
    00026 #include <winsock2.h>
    00027
    00028 #include "Avatar.h"
    00029 #include "CannedPackets.h"
    00030 #include "CharacterServer.h"
    00031 #include "PacketPipe.h"
    00032 #include "WorldServer.h"
    00033 #include "Job.h"
    00034
    00035 typedef enum { NO_SERVER = 0, CHAR_SERVER, WORLD_SERVER } SERVER;
    00036
    00037 class cRecvPacket;
    00038 class cMessage;
    00039
    00040 class cClient
    00041 {
    00042         friend class cMasterServer;
    00043         friend class cWorldManager;
    00044         friend class cCommandParser;
    00045         friend class cAllegiance;
    00046         friend class cFellowship;
    00047         friend class cNPC;
    00048         friend class cAltar;
    00049         friend class cDoor;
    00050         friend class cChest;
    00051         friend class cLifestone;
    00052         friend class cWeapon;
    00053         friend class cAbiotic;
    00054         friend class cPortal;
    00055         friend class cArmor;
    00056         friend class cCovenant;
    00057         friend class cHouse;
    00058         friend class cHooks;
    00059         friend class cStorage;
    00060         friend class cMonster;
    00061         friend class cMonsterServer;
    00062         friend class cObject;
    00063         friend class cAvatar;
    00064         friend class cPets;
    00065         friend class cCorpse;
    00066         friend class cWorldObject;
    00067         friend class cFood;
    00068         friend class cFoodContainer;
    00069         friend class cMerchantSign;
    00070         friend class cScrolls;
    00071         friend class cHealingKits;
    00072         friend class cGems;
    00073         friend class cBooks;
    00074         friend class cManaStones;
    00075         friend class cLockpicks;
    00076         friend class cWands;
    00077         friend class cTradeSkillMats;
    00078         friend class cSpellComps;
    00079         friend class cAmmo;
    00080         friend class cSalvage;
    00081         friend class cPyreals;
    00082         friend class cJewelry;
    00083         friend class cHealingCon;
    00084         friend class cWandCon;
    00085         friend class cCompCon;
    00086         friend class cTradeNotes;
    00087         friend class cPlants;
    00088         friend class cWeapon;
    00089         friend class cClothes;
    00090         friend class cPack;
    00091         friend class cShield;
    00092         friend class cFoci;
    00093         friend class TreasureGen;
    00094         friend class cMisc;
    00095         friend class cWarSpell;
    00096         friend class SimpleAI;
    00097         friend class cEnchantment;
    00098
    00099 public:
    00100         cClient ( SOCKADDR_IN& saSockAddr, BOOL fAddToHash = TRUE )
    00101                 :       m_dwF7B0Sequence( 0 ),
    00102                         m_dwLastRecvTime( 0 ),
    00103                         m_bCharState    ( 1 ),
    00104                         m_bWorldState   ( 0 ),
    00105                         m_saSockAddr    ( saSockAddr ),
    00106                         m_pcAvatar              ( NULL ),
    00107                         m_pcPrev                ( NULL ),
    00108                         m_pcNext                ( NULL )
    00109         {
    00110                 m_PacketPipe_WS.Initialize( );
    00111                 m_PacketPipe_CS.Initialize( );
    00112
    00113                 if ( fAddToHash )
    00114                         Hash_Add( this );
    00115         }
    00116
    00117         cClient ( )     {}
    00118         ~cClient( )
    00119         {
    00120                 const WORD wSum = Hash_AddrSum( m_saSockAddr );
    00121                 if ( m_pcPrev ) m_pcPrev->m_pcNext = m_pcNext; //crashes attacking; 0xC0000005 access error
    00122                 else                    m_lpcHashTable[wSum] = m_pcNext;
    00123                 if ( m_pcNext ) m_pcNext->m_pcPrev = m_pcPrev;
    00124         }
    00125
    00126         static inline void Hash_Load( )
    00127         {
    00128                 ZeroMemory( m_lpcHashTable, sizeof( m_lpcHashTable ) );
    00129         }
    00130
    00131         static inline cClient *Hash_New( SOCKADDR_IN& saSockAddr )
    00132         {
    00133                 cClient *pcClient = Hash_Find( saSockAddr );
    00134                 if ( pcClient )
    00135                         return pcClient;
    00136
    00137                 return new cClient( saSockAddr );
    00138         }
    00139
    00140         static void             Hash_Erase      ( );
    00141         static void             Hash_Remove     ( cClient *pcClient );
    00142         static cClient  *FindClient     ( DWORD dwGUID );
    00143         static cClient  *FindClient     ( char *szName );
    00144         static cAvatar  *FindAvatar     ( DWORD dwGUID );
    00145         static cAvatar  *FindAvatar     ( char *szName );
    00146
    00147         static inline void SendOffAllPackets( )
    00148         {
    00149                 cClient *pcClient;
    00150                 for ( int i = 0; i < 1020; ++i )
    00151                 {
    00152                         pcClient = m_lpcHashTable[i];
    00153                         while ( pcClient )
    00154                         {
    00155                                 pcClient->SendQueuedPackets( );
    00156                                 pcClient = pcClient->m_pcNext;
    00157                         }
    00158                 }
    00159         }
    00160
    00161         static inline void SendToAllClients( cMessage& cmData, WORD wGroup )
    00162         {
    00163                 cClient *pcClient;
    00164                 for ( int i = 0; i < 1020; ++i )
    00165                 {
    00166                         pcClient = m_lpcHashTable[i];
    00167                         while ( pcClient )
    00168                         {
    00169                                 if ( pcClient->m_pcAvatar )
    00170                                         pcClient->AddPacket( WORLD_SERVER, cmData, wGroup );
    00171
    00172                                 pcClient = pcClient->m_pcNext;
    00173                         }
    00174                 }
    00175         }
    00176
    00177         static inline void SendToAllClients( BYTE *pbData, WORD wSize, WORD wGroup )
    00178         {
    00179                 cClient *pcClient;
    00180                 for ( int i = 0; i < 1020; ++i )
    00181                 {
    00182                         pcClient = m_lpcHashTable[i];
    00183                         while ( pcClient )
    00184                         {
    00185                                 if ( pcClient->m_pcAvatar )
    00186                                         pcClient->AddPacket( WORLD_SERVER, pbData, wSize, wGroup );
    00187
    00188                                 pcClient = pcClient->m_pcNext;
    00189                         }
    00190                 }
    00191         }
    00192
    00193         static inline void SendToAllOtherClients( cClient *pcClientOrg, BYTE *pbData, WORD wSize, WORD wGroup )
    00194         {
    00195                 cClient *pcClient;
    00196                 for ( int i = 0; i < 1020; ++i )
    00197                 {
    00198                         pcClient = m_lpcHashTable[i];
    00199                         while ( pcClient )
    00200                         {
    00201                                 if ( pcClient->m_pcAvatar && pcClientOrg != pcClient )
    00202                                         pcClient->AddPacket( WORLD_SERVER, pbData, wSize, wGroup );
    00203
    00204                                 pcClient = pcClient->m_pcNext;
    00205                         }
    00206                 }
    00207         }
    00208
    00209         static inline void SendToAllOtherClients( cClient *pcClientOrg, cMessage& cmData, WORD wGroup )
    00210         {
    00211                 cClient *pcClient;
    00212                 for ( int i = 0; i < 1020; ++i )
    00213                 {
    00214                         pcClient = m_lpcHashTable[i];
    00215                         while ( pcClient )
    00216                         {
    00217                                 if ( pcClient->m_pcAvatar && pcClientOrg != pcClient )
    00218                                         pcClient->AddPacket( WORLD_SERVER, cmData, wGroup );
    00219
    00220                                 pcClient = pcClient->m_pcNext;
    00221                         }
    00222                 }
    00223         }
    00224
    00225         inline void AddPacket( SERVER eServer, BYTE *pbData, WORD wSize, WORD wGroup )
    00226         {
    00227                 if              ( eServer == WORLD_SERVER )     m_PacketPipe_WS.AddPacket( pbData, wSize, wGroup );
    00228                 else if ( eServer == CHAR_SERVER )      m_PacketPipe_CS.AddPacket( pbData, wSize, wGroup );
    00229         }
    00230         inline void AddPacket( SERVER eServer, cMessage& cmPacket, WORD wGroup )
    00231         {
    00232                 if              ( eServer == WORLD_SERVER ) m_PacketPipe_WS.AddPacket( cmPacket, wGroup );
    00233                 else if ( eServer == CHAR_SERVER )      m_PacketPipe_CS.AddPacket( cmPacket, wGroup );
    00234         }
    00235         inline void SendQueuedPackets( )
    00236         {
    00237                 m_PacketPipe_WS.SendQueuedPackets( m_saSockAddr );
    00238                 m_PacketPipe_CS.SendQueuedPackets( m_saSockAddr );
    00239         }
    00240
    00241         void ProcessPacket_CS( cRecvPacket *pcRecvPacket );
    00242         void ProcessPacket_WS( cRecvPacket *pcRecvPacket );
    00243
    00244         SOCKADDR_IN             m_saSockAddr;
    00245         cClient *m_pcNext;
    00246         cClient *m_pcPrev;
    00247         //char  m_szAccountName[45];
    00248
    00249 private:
    00250         static cClient *m_lpcHashTable[1020];
    00251
    00252         // Character Server functions
    00253         //========================================
    00254         inline void SendPacketF7B8      ( );
    00255         void            SendMOTD                ( );
    00256         inline void SendPacketF7C7      ( );
    00257         void            SendAddress             ( char *szAddr, WORD wPort );
    00258         void            SendAvatarList  ( );
    00259         void            SendDeleteAck   ( );
    00260         //========================================
    00261
    00262         // World Server functions
    00263         //========================================
    00264         inline void SendPacket100( );
    00265         inline void SendPacket400( );
    00266         //========================================
    00267
    00268
    00269
    00270         static inline void Hash_Add( cClient *pcClient )
    00271         {
    00272                 const WORD wSum = Hash_AddrSum( pcClient->m_saSockAddr );
    00273                 if ( !m_lpcHashTable[wSum] )
    00274                         m_lpcHashTable[wSum] = pcClient;
    00275                 else
    00276                 {
    00277                         pcClient->m_pcNext                              = m_lpcHashTable[wSum];
    00278                         m_lpcHashTable[wSum]->m_pcPrev  = pcClient;
    00279                         m_lpcHashTable[wSum]                    = pcClient;
    00280                 }
    00281         }
    00282
    00283         static inline cClient *Hash_Find( SOCKADDR_IN& saSockAddr )
    00284         {
    00285                 const WORD wSum = Hash_AddrSum( saSockAddr );
    00286                 cClient *pcClient = m_lpcHashTable[wSum];
    00287                 while ( pcClient )
    00288                 {
    00289                         if ( pcClient->CompareAddress( saSockAddr ) )   return pcClient;
    00290                         else                                                                                    pcClient = pcClient->m_pcNext;
    00291                 }
    00292                 return NULL;
    00293         }
    00294
    00295         static inline WORD Hash_AddrSum( SOCKADDR_IN& saSockAddr )
    00296         {
    00297                 return  HIBYTE( HIWORD( saSockAddr.sin_addr.S_un.S_addr ) ) + LOBYTE( HIWORD( saSockAddr.sin_addr.S_un.S_addr ) ) +
    00298                                 HIBYTE( LOWORD( saSockAddr.sin_addr.S_un.S_addr ) ) + LOBYTE( LOWORD( saSockAddr.sin_addr.S_un.S_addr ) );
    00299         }
    00300
    00301         inline BOOL CompareAddress( SOCKADDR_IN& saSockAddr )
    00302         {
    00303                 if      (       saSockAddr.sin_addr.S_un.S_addr == m_saSockAddr.sin_addr.S_un.S_addr &&
    00304                                 saSockAddr.sin_port == m_saSockAddr.sin_port )
    00305                         return TRUE;
    00306                 else
    00307                         return FALSE;
    00308         }
    00309
    00310         DWORD   m_dwF7B0Sequence;
    00311         DWORD   m_dwLastRecvTime;
    00312         BYTE    m_bCharState;
    00313         BYTE    m_bWorldState;
    00314         WORD    m_wAccountNameLength;
    00315         char    m_szAccountName[45];
    00316         DWORD   m_dwAccountID;
    00317
    00318         cAvatar *m_pcAvatar;
    00319
    00320         cPacketPipe< cCharacterServer > m_PacketPipe_CS;
    00321         cPacketPipe< cWorldServer >             m_PacketPipe_WS;
    00322         std::vector< cAvatarList >              m_AvatarList;
    00323 };
    00324
    00325 /*Karki's Mindless Shove
    00326 void cClient::ServerMessage( DWORD dwColor, cClient *pcClient, char *szMessage, ... )
    00327 {
    00328         char    szTextBuffer[1024];
    00329
    00330         va_list valMaker;
    00331
    00332         va_start( valMaker, szMessage );
    00333         wvsprintf( szTextBuffer, szMessage, valMaker );
    00334
    00335         cMessage cmSM;
    00336         cmSM << 0xF62CL << szTextBuffer << dwColor;
    00337
    00338         if ( pcClient == NULL )
    00339                 cClient::SendToAllClients( cmSM, 4 );
    00340         else
    00341                 pcClient->AddPacket( WORLD_SERVER, cmSM, 4 );
    00342 }
    00343 End Karki's Madness*/
    00344
    00345 //Inline Functions
    00346 //================
    00347
    00348 inline void cClient::SendPacketF7B8( )
    00349 {
    00350         BYTE MSG_F7B8[44] = { //Dec 28 //June 44
    00351         /*
    00352         // Dec [28]
    00353                 0xB8, 0xF7, 0x00, 0x00, 0x2D, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x04, 0x00, 0x00,
    00354                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    00355         };
    00356         */
    00357
    00358         // June   [44]
    00359                 0xB8, 0xF7, 0x00, 0x00, 0x90, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x05, 0x00, 0x00, 0x00,
    00360                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x11, 0x07, 0x00, 0x00, 0x00,
    00361                 0x00, 0x80, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x07, 0x00,
    00362         };
    00363
    00364         AddPacket( CHAR_SERVER, (BYTE *)MSG_F7B8, 44, 7 ); //Dec 28,7 //June 44,7
    00365         AddPacket( CHAR_SERVER, (BYTE *)MSG_F7B8, 44, 7 );
    00366 }
    00367
    00368 inline void cClient::SendPacketF7C7( )
    00369 {
    00370         DWORD dwCharSel = 0x0000F7C7;
    00371         AddPacket( CHAR_SERVER, (BYTE *)&dwCharSel, 4, 4 );
    00372 }
    00373
    00374 inline void cClient::SendPacket100( )
    00375 {
    00376         m_PacketPipe_WS.CalcCRC( SERVER_Packet100, 70 );
    00377
    00378         sendto( m_PacketPipe_WS.m_Socket, (char *)SERVER_Packet100, 90, NULL, (SOCKADDR *)&m_saSockAddr, sizeof( SOCKADDR ) );
    00379 }
    00380
    00381 inline void cClient::SendPacket400( )
    00382 {
    00383         m_PacketPipe_WS.CalcCRC( SERVER_Packet400, 8 );
    00384
    00385         sendto( m_PacketPipe_WS.m_Socket, (char *)SERVER_Packet400, 28, NULL, (SOCKADDR *)&m_saSockAddr, sizeof( SOCKADDR ) );
    00386 }
    00387
    00388 #endif  // #ifndef __CLIENT_H