Clone of UAS2 @ https://github.com/drudgedance/uas2

Client.h 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*
  2. * This file is part of UAS2.
  3. *
  4. * UAS2 is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * UAS2 is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. * You should have received a copy of the GNU General Public License
  14. * along with UASv1; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. /**
  18. * @file Client.h
  19. */
  20. #ifndef __CLIENT_H
  21. #define __CLIENT_H
  22. #include <winsock2.h>
  23. #include "Avatar.h"
  24. #include "CannedPackets.h"
  25. #include "CharacterServer.h"
  26. #include "PacketPipe.h"
  27. #include "WorldServer.h"
  28. #include "Job.h"
  29. typedef enum { NO_SERVER = 0, CHAR_SERVER, WORLD_SERVER } SERVER;
  30. class cRecvPacket;
  31. class cMessage;
  32. class cClient
  33. {
  34. friend class cMasterServer;
  35. friend class cWorldManager;
  36. friend class cCommandParser;
  37. friend class cAllegiance;
  38. friend class cFellowship;
  39. friend class cNPC;
  40. friend class cAltar;
  41. friend class cDoor;
  42. friend class cChest;
  43. friend class cLifestone;
  44. friend class cWeapon;
  45. friend class cAbiotic;
  46. friend class cPortal;
  47. friend class cArmor;
  48. friend class cCovenant;
  49. friend class cHouse;
  50. friend class cHooks;
  51. friend class cStorage;
  52. friend class cMonster;
  53. friend class cMonsterServer;
  54. friend class cObject;
  55. friend class cAvatar;
  56. friend class cPets;
  57. friend class cCorpse;
  58. friend class cWorldObject;
  59. friend class cFood;
  60. friend class cFoodContainer;
  61. friend class cMerchantSign;
  62. friend class cScrolls;
  63. friend class cHealingKits;
  64. friend class cGems;
  65. friend class cBooks;
  66. friend class cManaStones;
  67. friend class cLockpicks;
  68. friend class cWands;
  69. friend class cTradeSkillMats;
  70. friend class cSpellComps;
  71. friend class cAmmo;
  72. friend class cSalvage;
  73. friend class cPyreals;
  74. friend class cJewelry;
  75. friend class cHealingCon;
  76. friend class cWandCon;
  77. friend class cCompCon;
  78. friend class cTradeNotes;
  79. friend class cPlants;
  80. friend class cWeapon;
  81. friend class cClothes;
  82. friend class cPack;
  83. friend class cShield;
  84. friend class cFoci;
  85. friend class TreasureGen;
  86. friend class cMisc;
  87. friend class cWarSpell;
  88. friend class SimpleAI;
  89. friend class cEnchantment;
  90. public:
  91. cClient ( SOCKADDR_IN& saSockAddr, BOOL fAddToHash = TRUE )
  92. : m_dwF7B0Sequence( 0 ),
  93. m_dwLastRecvTime( 0 ),
  94. m_bCharState ( 1 ),
  95. m_bWorldState ( 0 ),
  96. m_saSockAddr ( saSockAddr ),
  97. m_pcAvatar ( NULL ),
  98. m_pcPrev ( NULL ),
  99. m_pcNext ( NULL )
  100. {
  101. m_PacketPipe_WS.Initialize( );
  102. m_PacketPipe_CS.Initialize( );
  103. if ( fAddToHash )
  104. Hash_Add( this );
  105. }
  106. cClient ( ) {}
  107. ~cClient( )
  108. {
  109. const WORD wSum = Hash_AddrSum( m_saSockAddr );
  110. if ( m_pcPrev ) m_pcPrev->m_pcNext = m_pcNext; //crashes attacking; 0xC0000005 access error
  111. else m_lpcHashTable[wSum] = m_pcNext;
  112. if ( m_pcNext ) m_pcNext->m_pcPrev = m_pcPrev;
  113. }
  114. static inline void Hash_Load( )
  115. {
  116. ZeroMemory( m_lpcHashTable, sizeof( m_lpcHashTable ) );
  117. }
  118. static inline cClient *Hash_New( SOCKADDR_IN& saSockAddr )
  119. {
  120. cClient *pcClient = Hash_Find( saSockAddr );
  121. if ( pcClient )
  122. return pcClient;
  123. return new cClient( saSockAddr );
  124. }
  125. static void Hash_Erase ( );
  126. static void Hash_Remove ( cClient *pcClient );
  127. static cClient *FindClient ( DWORD dwGUID );
  128. static cClient *FindClient ( char *szName );
  129. static cAvatar *FindAvatar ( DWORD dwGUID );
  130. static cAvatar *FindAvatar ( char *szName );
  131. static inline void SendOffAllPackets( )
  132. {
  133. cClient *pcClient;
  134. for ( int i = 0; i < 1020; ++i )
  135. {
  136. pcClient = m_lpcHashTable[i];
  137. while ( pcClient )
  138. {
  139. pcClient->SendQueuedPackets( );
  140. pcClient = pcClient->m_pcNext;
  141. }
  142. }
  143. }
  144. static inline void SendToAllClients( cMessage& cmData, WORD wGroup )
  145. {
  146. cClient *pcClient;
  147. for ( int i = 0; i < 1020; ++i )
  148. {
  149. pcClient = m_lpcHashTable[i];
  150. while ( pcClient )
  151. {
  152. if ( pcClient->m_pcAvatar )
  153. pcClient->AddPacket( WORLD_SERVER, cmData, wGroup );
  154. pcClient = pcClient->m_pcNext;
  155. }
  156. }
  157. }
  158. static inline void SendToAllClients( BYTE *pbData, WORD wSize, WORD wGroup )
  159. {
  160. cClient *pcClient;
  161. for ( int i = 0; i < 1020; ++i )
  162. {
  163. pcClient = m_lpcHashTable[i];
  164. while ( pcClient )
  165. {
  166. if ( pcClient->m_pcAvatar )
  167. pcClient->AddPacket( WORLD_SERVER, pbData, wSize, wGroup );
  168. pcClient = pcClient->m_pcNext;
  169. }
  170. }
  171. }
  172. static inline void SendToAllOtherClients( cClient *pcClientOrg, BYTE *pbData, WORD wSize, WORD wGroup )
  173. {
  174. cClient *pcClient;
  175. for ( int i = 0; i < 1020; ++i )
  176. {
  177. pcClient = m_lpcHashTable[i];
  178. while ( pcClient )
  179. {
  180. if ( pcClient->m_pcAvatar && pcClientOrg != pcClient )
  181. pcClient->AddPacket( WORLD_SERVER, pbData, wSize, wGroup );
  182. pcClient = pcClient->m_pcNext;
  183. }
  184. }
  185. }
  186. static inline void SendToAllOtherClients( cClient *pcClientOrg, cMessage& cmData, WORD wGroup )
  187. {
  188. cClient *pcClient;
  189. for ( int i = 0; i < 1020; ++i )
  190. {
  191. pcClient = m_lpcHashTable[i];
  192. while ( pcClient )
  193. {
  194. if ( pcClient->m_pcAvatar && pcClientOrg != pcClient )
  195. pcClient->AddPacket( WORLD_SERVER, cmData, wGroup );
  196. pcClient = pcClient->m_pcNext;
  197. }
  198. }
  199. }
  200. inline void AddPacket( SERVER eServer, BYTE *pbData, WORD wSize, WORD wGroup )
  201. {
  202. if ( eServer == WORLD_SERVER ) m_PacketPipe_WS.AddPacket( pbData, wSize, wGroup );
  203. else if ( eServer == CHAR_SERVER ) m_PacketPipe_CS.AddPacket( pbData, wSize, wGroup );
  204. }
  205. inline void AddPacket( SERVER eServer, cMessage& cmPacket, WORD wGroup )
  206. {
  207. if ( eServer == WORLD_SERVER ) m_PacketPipe_WS.AddPacket( cmPacket, wGroup );
  208. else if ( eServer == CHAR_SERVER ) m_PacketPipe_CS.AddPacket( cmPacket, wGroup );
  209. }
  210. inline void SendQueuedPackets( )
  211. {
  212. m_PacketPipe_WS.SendQueuedPackets( m_saSockAddr );
  213. m_PacketPipe_CS.SendQueuedPackets( m_saSockAddr );
  214. }
  215. void ProcessPacket_CS( cRecvPacket *pcRecvPacket );
  216. void ProcessPacket_WS( cRecvPacket *pcRecvPacket );
  217. SOCKADDR_IN m_saSockAddr;
  218. cClient *m_pcNext;
  219. cClient *m_pcPrev;
  220. //char m_szAccountName[45];
  221. private:
  222. static cClient *m_lpcHashTable[1020];
  223. // Character Server functions
  224. //========================================
  225. inline void SendPacketF7B8 ( );
  226. void SendMOTD ( );
  227. inline void SendPacketF7C7 ( );
  228. void SendAddress ( char *szAddr, WORD wPort );
  229. void SendAvatarList ( );
  230. void SendDeleteAck ( );
  231. //========================================
  232. // World Server functions
  233. //========================================
  234. inline void SendPacket100( );
  235. inline void SendPacket400( );
  236. //========================================
  237. static inline void Hash_Add( cClient *pcClient )
  238. {
  239. const WORD wSum = Hash_AddrSum( pcClient->m_saSockAddr );
  240. if ( !m_lpcHashTable[wSum] )
  241. m_lpcHashTable[wSum] = pcClient;
  242. else
  243. {
  244. pcClient->m_pcNext = m_lpcHashTable[wSum];
  245. m_lpcHashTable[wSum]->m_pcPrev = pcClient;
  246. m_lpcHashTable[wSum] = pcClient;
  247. }
  248. }
  249. static inline cClient *Hash_Find( SOCKADDR_IN& saSockAddr )
  250. {
  251. const WORD wSum = Hash_AddrSum( saSockAddr );
  252. cClient *pcClient = m_lpcHashTable[wSum];
  253. while ( pcClient )
  254. {
  255. if ( pcClient->CompareAddress( saSockAddr ) ) return pcClient;
  256. else pcClient = pcClient->m_pcNext;
  257. }
  258. return NULL;
  259. }
  260. static inline WORD Hash_AddrSum( SOCKADDR_IN& saSockAddr )
  261. {
  262. return HIBYTE( HIWORD( saSockAddr.sin_addr.S_un.S_addr ) ) + LOBYTE( HIWORD( saSockAddr.sin_addr.S_un.S_addr ) ) +
  263. HIBYTE( LOWORD( saSockAddr.sin_addr.S_un.S_addr ) ) + LOBYTE( LOWORD( saSockAddr.sin_addr.S_un.S_addr ) );
  264. }
  265. inline BOOL CompareAddress( SOCKADDR_IN& saSockAddr )
  266. {
  267. if ( saSockAddr.sin_addr.S_un.S_addr == m_saSockAddr.sin_addr.S_un.S_addr &&
  268. saSockAddr.sin_port == m_saSockAddr.sin_port )
  269. return TRUE;
  270. else
  271. return FALSE;
  272. }
  273. DWORD m_dwF7B0Sequence;
  274. DWORD m_dwLastRecvTime;
  275. BYTE m_bCharState;
  276. BYTE m_bWorldState;
  277. WORD m_wAccountNameLength;
  278. char m_szAccountName[45];
  279. DWORD m_dwAccountID;
  280. cAvatar *m_pcAvatar;
  281. cPacketPipe< cCharacterServer > m_PacketPipe_CS;
  282. cPacketPipe< cWorldServer > m_PacketPipe_WS;
  283. std::vector< cAvatarList > m_AvatarList;
  284. };
  285. /*Karki's Mindless Shove
  286. void cClient::ServerMessage( DWORD dwColor, cClient *pcClient, char *szMessage, ... )
  287. {
  288. char szTextBuffer[1024];
  289. va_list valMaker;
  290. va_start( valMaker, szMessage );
  291. wvsprintf( szTextBuffer, szMessage, valMaker );
  292. cMessage cmSM;
  293. cmSM << 0xF62CL << szTextBuffer << dwColor;
  294. if ( pcClient == NULL )
  295. cClient::SendToAllClients( cmSM, 4 );
  296. else
  297. pcClient->AddPacket( WORLD_SERVER, cmSM, 4 );
  298. }
  299. End Karki's Madness*/
  300. //Inline Functions
  301. //================
  302. inline void cClient::SendPacketF7B8( )
  303. {
  304. BYTE MSG_F7B8[44] = { //Dec 28 //June 44
  305. /*
  306. // Dec [28]
  307. 0xB8, 0xF7, 0x00, 0x00, 0x2D, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x04, 0x00, 0x00,
  308. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  309. };
  310. */
  311. // June [44]
  312. 0xB8, 0xF7, 0x00, 0x00, 0x90, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x05, 0x00, 0x00, 0x00,
  313. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x11, 0x07, 0x00, 0x00, 0x00,
  314. 0x00, 0x80, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x07, 0x00,
  315. };
  316. AddPacket( CHAR_SERVER, (BYTE *)MSG_F7B8, 44, 7 ); //Dec 28,7 //June 44,7
  317. AddPacket( CHAR_SERVER, (BYTE *)MSG_F7B8, 44, 7 );
  318. }
  319. inline void cClient::SendPacketF7C7( )
  320. {
  321. DWORD dwCharSel = 0x0000F7C7;
  322. AddPacket( CHAR_SERVER, (BYTE *)&dwCharSel, 4, 4 );
  323. }
  324. inline void cClient::SendPacket100( )
  325. {
  326. m_PacketPipe_WS.CalcCRC( SERVER_Packet100, 70 );
  327. sendto( m_PacketPipe_WS.m_Socket, (char *)SERVER_Packet100, 90, NULL, (SOCKADDR *)&m_saSockAddr, sizeof( SOCKADDR ) );
  328. }
  329. inline void cClient::SendPacket400( )
  330. {
  331. m_PacketPipe_WS.CalcCRC( SERVER_Packet400, 8 );
  332. sendto( m_PacketPipe_WS.m_Socket, (char *)SERVER_Packet400, 28, NULL, (SOCKADDR *)&m_saSockAddr, sizeof( SOCKADDR ) );
  333. }
  334. #endif // #ifndef __CLIENT_H