00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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;
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
00248
00249 private:
00250 static cClient *m_lpcHashTable[1020];
00251
00252
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
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
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 inline void cClient::SendPacketF7B8( )
00349 {
00350 BYTE MSG_F7B8[44] = {
00351
00352
00353
00354
00355
00356
00357
00358
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 );
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