S3PDBSocketPool.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:32k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //-----------------------------------------//
  2. //                                         //
  3. //  File : S3PDBSocketPool.cpp    //
  4. // Author : Yang Xiaodong            //
  5. // Modified : 8/26/2002                //
  6. //                                         //
  7. //-----------------------------------------//
  8. #pragma warning(disable: 4786)
  9. #include "S3PDBSocketPool.h"
  10. #include "../../../Headers/inoutmac.h"
  11. #include "S3PAccount.h"
  12. #include "GlobalFun.h"
  13. #include "S3PDBConnectionPool.h"
  14. #include "../../Multiserver/Heaven/Interface/IServer.h"
  15. #include "../../../Headers/KProtocolDef.h"
  16. #include "../../../Headers/KRelayProtocol.h"
  17. #include "../../../Headers/KGmProtocol.h"
  18. #include "../../../Headers/KProtocol.h"
  19. #include "../S3AccServer/AccountLoginDef.h"
  20. #include "crtdbg.h"
  21. #include "string.h"
  22. #include "malloc.h"
  23. S3PDBSocketPool* S3PDBSocketPool::m_pInstance = NULL;
  24. DWORD S3PDBSocketPool::m_SelfAddress = 0;
  25. S3PDBSocketPool::S3PDBSocketPool()
  26. {
  27. m_pServer = NULL;
  28. }
  29. S3PDBSocketPool::~S3PDBSocketPool()
  30. {
  31. assert(m_pServer == NULL);
  32. assert(m_clientIDs.size() == 0);
  33. }
  34. S3PDBSocketPool* S3PDBSocketPool::Instance()
  35. {
  36. if ( NULL == m_pInstance )
  37. {
  38. m_pInstance = new S3PDBSocketPool;
  39. gGetMacAndIPAddress(NULL, NULL, NULL, &m_pInstance->m_SelfAddress);
  40. }
  41. return m_pInstance;
  42. }
  43. void S3PDBSocketPool::ReleaseInstance()
  44. {
  45. delete m_pInstance;
  46. m_pInstance = NULL;
  47. }
  48. HANDLE S3PDBSocketPool::Start(IServer* pServer)
  49. {
  50. assert(pServer);
  51. if (NULL == m_pServer)
  52. {
  53. m_pServer = pServer;
  54. pServer->AddRef();
  55. }
  56. return 0;
  57. }
  58. BOOL S3PDBSocketPool::Stop()
  59. {
  60. BOOL bRet = TRUE;
  61. if (bRet && m_pServer)
  62. {
  63. StopAllUserClientConnect();
  64. m_pServer->Release();
  65. m_pServer = NULL;
  66. }
  67. return bRet;
  68. }
  69. BOOL S3PDBSocketPool::SendData(unsigned long uID, const void * const pData, const size_t &datalength)
  70. {
  71. if (m_pServer == NULL || pData == NULL || datalength <= 0)
  72. return FALSE;
  73. BOOL bRet = FALSE;
  74. try
  75. {
  76. m_pServer->SendData(uID, pData, datalength);
  77. bRet = TRUE;
  78. }
  79. catch(...)
  80. {
  81. //printf("Failed to feed back( S3PDBSocketPool::SendData )");
  82. bRet = FALSE;
  83. }
  84. return bRet;
  85. }
  86. BOOL S3PDBSocketPool::CustomSend(unsigned long uID, char nProtocol, KAccountHead* pSend)
  87. {
  88. if (m_pServer == NULL)
  89. return FALSE;
  90. BOOL bRet = FALSE;
  91. try
  92. {
  93. assert(pSend);
  94. pSend->Version = ACCOUNT_CURRENT_VERSION;
  95. char send[MAX_PATH + 1];
  96. assert(pSend->Size < MAX_PATH);
  97. send[0] = pf_normal;
  98. send[1] = nProtocol;
  99. memcpy(send + 2, pSend, pSend->Size);
  100. m_pServer->SendData(uID, send, pSend->Size + 2);
  101. bRet = TRUE;
  102. }
  103. catch(...)
  104. {
  105. //printf("Failed to feed back( S3PDBSocketPool::CustomSend )");
  106. bRet = FALSE;
  107. }
  108. return bRet;
  109. }
  110. void S3PDBSocketPool::SendRelayData(unsigned long uID, char* szAccount, const void * const pSrcData1, const size_t& datalength1, const void * const pSrcData2, const size_t& datalength2)
  111. {
  112. if (szAccount == NULL || pSrcData1 == NULL || datalength1 == 0)
  113. return;
  114. RELAY_ASKWAY_DATA relay;
  115. relay.ProtocolFamily = pf_relay;
  116. relay.ProtocolID = relay_c2c_askwaydata;
  117. relay.nFromIP = 0; //由于是服务器主动发给客户端,所以无法填nFromIP,只好填0
  118. relay.nFromRelayID = 0; //由于是服务器主动发给客户端,所以无法填nFromRelayID,只好填0
  119. relay.seekRelayCount = 0;
  120. relay.seekMethod = rm_account_id;
  121. relay.wMethodDataLength = defACCOUNT_STRING_LENGTH;
  122. relay.routeDateLength = datalength1 + datalength2;
  123. BYTE *pData = (BYTE *)_alloca(sizeof(relay) + relay.wMethodDataLength + relay.routeDateLength);
  124. BYTE *pDataOrg = pData;
  125. memcpy(pData, &relay, sizeof(relay));
  126. pData += sizeof(relay);
  127. strncpy((char*)pData, szAccount, defACCOUNT_STRING_LENGTH);
  128. pData += relay.wMethodDataLength;
  129. memcpy(pData, pSrcData1, datalength1);
  130. pData += datalength1;
  131. if (pSrcData2 && datalength2 > 0)
  132. memcpy(pData, pSrcData2, datalength2);
  133. m_pServer->SendData(uID ,(const void *)pDataOrg, sizeof(relay) + relay.wMethodDataLength + relay.routeDateLength);
  134. }
  135. void S3PDBSocketPool::SendRelayData(unsigned long uID, const void * const pSrcData1, const size_t& datalength1, const void * const pSrcData2, const size_t& datalength2)
  136. {
  137. if (pSrcData1 == NULL || datalength1 == 0)
  138. return;
  139. RELAY_DATA relayIP;
  140. relayIP.ProtocolFamily = pf_relay;
  141. relayIP.ProtocolID = relay_c2c_data;
  142. relayIP.nToIP = 0;
  143. relayIP.nToRelayID = 0;
  144. relayIP.nFromIP = 0; //由于是服务器主动发给客户端,所以无法填nFromIP,只好填0
  145. relayIP.nFromRelayID = 0; //由于是服务器主动发给客户端,所以无法填nFromRelayID,只好填0
  146. relayIP.routeDateLength = datalength1 + datalength2;
  147. BYTE *pData = (BYTE *)_alloca(sizeof(relayIP) + relayIP.routeDateLength);
  148. BYTE *pDataOrg = pData;
  149. memcpy(pData, &relayIP, sizeof(relayIP));
  150. pData += sizeof(relayIP);
  151. memcpy(pData, pSrcData1, datalength1);
  152. pData += datalength1;
  153. if (pSrcData2 && datalength2 > 0)
  154. memcpy(pData, pSrcData2, datalength2);
  155. m_pServer->SendData(uID ,(const void *)pDataOrg, sizeof(relayIP) + relayIP.routeDateLength);
  156. }
  157. BOOL S3PDBSocketPool::AddUserClientID(unsigned long uID)
  158. {
  159. GatewayIDMap::iterator i = m_clientIDs.find(uID);
  160. if (i != m_clientIDs.end())
  161. {
  162. if (i->second)
  163. {
  164. i->second->Stop();
  165. delete i->second;
  166. }
  167. }
  168. assert(m_pServer);
  169. Lock();
  170. const char* pInfo = m_pServer->GetClientInfo(uID);
  171. unsigned long Address = inet_addr(pInfo);
  172. int offset = 0;
  173. while(*(pInfo + offset) != ':')
  174. offset++;
  175. offset += 2; //skip : and blank
  176. short Port = atoi(pInfo + offset);
  177. KGatewayDataProcess* p = new KGatewayDataProcess(uID, Address, Port);
  178. m_clientIDs[uID] = p;
  179. Unlock();
  180. p->Start(m_pServer);
  181. gTrace("Add Relay(%s) Client %d ! -- Count %d", pInfo, uID, m_clientIDs.size());
  182. return TRUE;
  183. }
  184. BOOL S3PDBSocketPool::RemoveUserClientID(unsigned long uID)
  185. {
  186. BOOL b = FALSE;
  187. DWORD Address;
  188. std::string ServerName;
  189. KGatewayDataProcess* p = NULL;
  190. Lock();
  191. GatewayIDMap::iterator i = m_clientIDs.find(uID);
  192. if (i != m_clientIDs.end ())
  193. {
  194. if (i->second)
  195. {
  196. p = i->second;
  197. b = TRUE;
  198. }
  199. m_clientIDs.erase(i);
  200. }
  201. Unlock();
  202. gTrace("Remove Relay Client %d ! -- Count %d", uID, m_clientIDs.size());
  203. if (b && p)
  204. {
  205. p->Stop();
  206. Address = p->m_Address;
  207. ServerName = p->m_ServerName;
  208. delete p;
  209. NotifyRelayLogoutInfo(Address, ServerName);
  210. }
  211. return b;
  212. }
  213. BOOL S3PDBSocketPool::ShowAllClientInfo()
  214. {
  215. if (IsLocked())
  216. return FALSE;
  217. Lock();
  218. BOOL b = FALSE;
  219. GatewayIDMap::iterator i = m_clientIDs.begin();
  220. int n = 0;
  221. while (i != m_clientIDs.end())
  222. {
  223. KGatewayDataProcess* p = i->second;
  224. if (p)
  225. {
  226. in_addr add;
  227. add.s_addr = p->m_Address;
  228. gTrace("Client %d: %s(%s)", n, p->m_ServerName.c_str(), inet_ntoa(in_addr(add))); 
  229. }
  230. i++;
  231. n++;
  232. }
  233. b = TRUE;
  234. Unlock();
  235. return b;
  236. }
  237. BOOL S3PDBSocketPool::FindGatewayByServerName(const char* szServerName, DWORD& nGameID)
  238. {
  239. if (szServerName == NULL ||
  240. szServerName[0] == 0)
  241. {
  242. return FALSE;
  243. }
  244. Lock();
  245. BOOL b = FALSE;
  246. GatewayIDMap::iterator i = m_clientIDs.begin();
  247. while (i != m_clientIDs.end())
  248. {
  249. if (i->second && strcmp(i->second->m_ServerName.c_str(), szServerName) == 0)
  250. {
  251. nGameID = i->second->m_nGameID;
  252. b = TRUE;
  253. break;
  254. }
  255. i++;
  256. }
  257. Unlock();
  258. return b;
  259. }
  260. KGatewayDataProcess* S3PDBSocketPool::FindGatewayByID(unsigned long nGameID)
  261. {
  262. KGatewayDataProcess* p = NULL;
  263. Lock();
  264. GatewayIDMap::iterator i = m_clientIDs.begin();
  265. while (i != m_clientIDs.end())
  266. {
  267. if (i->second && i->second->m_nGameID == nGameID)
  268. {
  269. p = i->second;
  270. break;
  271. }
  272. i++;
  273. }
  274. Unlock();
  275. return p;
  276. }
  277. BOOL S3PDBSocketPool::FindGatewayClientByAddress(DWORD nAddress, DWORD& nClientID)
  278. {
  279. Lock();
  280. BOOL b = FALSE;
  281. GatewayIDMap::iterator i = m_clientIDs.begin();
  282. while (i != m_clientIDs.end())
  283. {
  284. if (i->second && i->second->m_Address == nAddress)
  285. {
  286. nClientID = i->first;
  287. b = TRUE;
  288. break;
  289. }
  290. i++;
  291. }
  292. Unlock();
  293. return b;
  294. }
  295. void S3PDBSocketPool::BroadGMData(const IBYTE* lpData, const DWORD dwDataSize)
  296. {
  297. Lock();
  298. GatewayIDMap::iterator i = m_clientIDs.begin();
  299. while (i != m_clientIDs.end())
  300. {
  301. if (i->second &&
  302. i->second->m_ServerName[0] == 'g' &&
  303. i->second->m_ServerName[1] == 'm' &&
  304. i->second->m_ServerName[2] == '-')
  305. {
  306. SendData(i->first, lpData, dwDataSize);
  307. }
  308. i++;
  309. }
  310. Unlock();
  311. }
  312. BOOL S3PDBSocketPool::StopAllUserClientConnect()
  313. {
  314. while(m_clientIDs.size() > 0)
  315. {
  316. GatewayIDMap::iterator i = m_clientIDs.begin();
  317. if (i != m_clientIDs.end() && i->second)
  318. i->second->Stop();
  319. Sleep(10);
  320. }
  321. return TRUE;
  322. }
  323. void S3PDBSocketPool::NotifyRelayLoginInfo(DWORD nGameID, DWORD nClientID, DWORD Address, const std::string& ServerName)
  324. {
  325. KServerInfo aInfo;
  326. aInfo.Size = sizeof(KServerInfo);
  327. aInfo.Type = ServerInfo;
  328. aInfo.Operate = 0;
  329. aInfo.Version = ACCOUNT_CURRENT_VERSION;
  330. aInfo.nValue = 0;
  331. Lock();
  332. GatewayIDMap::iterator i = m_clientIDs.begin();
  333. aInfo.nServerType = server_Login;
  334. aInfo.nValue = Address;
  335. strncpy(aInfo.Account, ServerName.c_str(), LOGIN_USER_ACCOUNT_MAX_LEN);
  336. while (i != m_clientIDs.end()) //先给已登陆者发送刚登陆者的信息
  337. {
  338. if (i->second)
  339. {
  340. if (i->second->m_nGameID != nGameID)
  341. {
  342. CustomSend(i->first, s2c_gatewayinfo, &aInfo);
  343. }
  344. }
  345. i++;
  346. }
  347. //再给刚登陆者发送已登陆者的信息
  348. aInfo.nServerType = server_LoginAlready;
  349. i = m_clientIDs.begin();
  350. while (i != m_clientIDs.end())
  351. {
  352. if (i->second)
  353. {
  354. if (i->second->m_nGameID != nGameID)
  355. {
  356. aInfo.nValue = i->second->m_Address;
  357. strncpy(aInfo.Account, i->second->m_ServerName.c_str(), LOGIN_USER_ACCOUNT_MAX_LEN);
  358. CustomSend(nClientID, s2c_gatewayinfo, &aInfo);
  359. }
  360. }
  361. i++;
  362. }
  363. Unlock();
  364. }
  365. void S3PDBSocketPool::NotifyRelayLogoutInfo(DWORD Address, const std::string& ServerName)
  366. {
  367. KServerInfo aInfo;
  368. aInfo.Size = sizeof(KServerInfo);
  369. aInfo.Type = ServerInfo;
  370. aInfo.Operate = 0;
  371. aInfo.Version = ACCOUNT_CURRENT_VERSION;
  372. aInfo.nValue = 0;
  373. Lock();
  374. GatewayIDMap::iterator i = m_clientIDs.begin();
  375. aInfo.nServerType = server_Logout;
  376. strncpy(aInfo.Account, ServerName.c_str(), LOGIN_USER_ACCOUNT_MAX_LEN);
  377. aInfo.nValue = Address;
  378. while (i != m_clientIDs.end())
  379. {
  380. if (i->second)
  381. {
  382. CustomSend(i->first, s2c_gatewayinfo, &aInfo);
  383. }
  384. i++;
  385. }
  386. Unlock();
  387. }
  388. //////////////////////////////////////////////////////////////////////////////////////
  389. KGatewayDataProcess::KGatewayDataProcess(unsigned long nID, unsigned long Address, short Port)
  390. {
  391. m_nClientID = nID;
  392. m_Address = Address;
  393. m_Port = Port;
  394. m_nGameID = 0;
  395. m_hClosed = KPICreateEvent(NULL, TRUE, FALSE, NULL);
  396. m_hStartAutoTime = KPICreateEvent(NULL, TRUE, FALSE, NULL);
  397. m_pServer = NULL;
  398. m_pConn = NULL;
  399. }
  400. KGatewayDataProcess::~KGatewayDataProcess()
  401. {
  402. assert(m_pServer == NULL);
  403. }
  404. void KGatewayDataProcess::Close()
  405. {
  406. if (m_nGameID > 0)
  407. {
  408. S3PDBConVBC* pCon = GetDB(1);
  409. KAccountUser acc;
  410. acc.Size = sizeof(KAccountUser);
  411. acc.Type = AccountUser;
  412. acc.Version = ACCOUNT_CURRENT_VERSION;
  413. acc.Operate = m_nGameID;
  414. acc.Account[0] = 0;
  415. ProRelayClose(pCon, (const IBYTE*)&acc, acc.Size);
  416. KPIWaitForSingleObject(m_hClosed, INFINITE);
  417. }
  418. }
  419. void KGatewayDataProcess::AutoTime()
  420. {
  421. if (!IsStartAutoTime())
  422. return;
  423. DWORD nNow = GetTickCount();
  424. if (nNow - m_LastMoneyTime >= 600000) //十分钟催一次钱
  425. {
  426. m_LastMoneyTime = nNow;
  427. S3PDBConVBC* pConn = GetDB(0);
  428. if (pConn)
  429. ProAutoTime(pConn);
  430. }
  431. if (nNow - m_LastPingTime >= 180000) //三分钟没有Ping
  432. {
  433. KPISetEvent(m_hStop);
  434. }
  435. }
  436. BOOL KGatewayDataProcess::CheckConnectAddress()
  437. {
  438. S3PDBConVBC* pConn = GetDB(0);
  439. if (pConn)
  440. return S3PAccount::CheckAddress(pConn, m_Address, m_Port) == ACTION_SUCCESS;
  441. return FALSE;
  442. }
  443. BOOL KGatewayDataProcess::IsStartAutoTime()
  444. {
  445. return KPIWaitForSingleObject(m_hStartAutoTime, 0) == 1;
  446. }
  447. BOOL KGatewayDataProcess::StartAutoTime()
  448. {
  449. if (!IsStartAutoTime())
  450. {
  451. m_LastPingTime = GetTickCount();
  452. m_LastMoneyTime = m_LastPingTime;
  453. KPISetEvent(m_hStartAutoTime);
  454. }
  455. return TRUE;
  456. }
  457. void KGatewayDataProcess::ProcessClientData(const void * pData, DWORD dwDataSize)
  458. {
  459. if (pData && dwDataSize > 0)
  460. {
  461. BYTE nFamily = *((char*)pData);
  462. BYTE nProtocol = *(((char*)pData) + 1);
  463. if (nFamily == pf_normal && nProtocol == c2s_ping)
  464. {
  465. DWORD nSecond = m_LastPingTime;
  466. m_LastPingTime = GetTickCount();
  467. #pragma pack(push, 1)
  468. typedef struct
  469. {
  470. BYTE nFamily;
  471. BYTE ProtocolType;
  472. DWORD m_dwTime;
  473. } PING_COMMAND;
  474. #pragma pack(pop)
  475. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  476. PING_COMMAND* p = (PING_COMMAND*)pData;
  477. PING_COMMAND PingCmd;
  478. PingCmd.nFamily = pf_normal;
  479. PingCmd.ProtocolType = s2c_ping;
  480. PingCmd.m_dwTime = p->m_dwTime;
  481. pSocket->SendData(m_nClientID, &PingCmd, sizeof(PING_COMMAND));
  482. in_addr ar;
  483. ar.s_addr = m_Address;
  484. gTrace("Relay %s(%s): Ping %d(s)", m_ServerName.c_str(), inet_ntoa(ar), (m_LastPingTime - nSecond) / 1000);
  485. }
  486. else if (nFamily == pf_relay && (nProtocol == relay_c2c_data || nProtocol == relay_s2c_loseway))
  487. {
  488. ProRelayIPData((const IBYTE*)pData, dwDataSize);
  489. }
  490. else
  491. {
  492. //不需要数据库的在前面处理
  493. S3PDBConVBC* pConn = GetDB(10);
  494. ProcessData(pConn, pData, dwDataSize);
  495. }
  496. }
  497. }
  498. DWORD KGatewayDataProcess::ProcessData(S3PDBConVBC* pConn, const void* pData, DWORD dwDataSize)
  499. {
  500. BOOL bRet = FALSE;
  501. if (pConn == NULL || pData == NULL || dwDataSize <= 0)
  502. {
  503. return bRet;
  504. }
  505. BYTE nFamily = *((char*)pData);
  506. BYTE nProtocol = *(((char*)pData) + 1);
  507. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  508. BOOL bStopConn = FALSE;
  509. if (nFamily == pf_normal && nProtocol == c2s_gatewayverify)
  510. {
  511. if (m_nGameID > 0)
  512. {
  513. KAccountUserReturn aReturn;
  514. aReturn.Size = sizeof(KAccountUserReturn);
  515. aReturn.Type = AccountUserReturn;
  516. aReturn.Operate = ((KAccountUserLoginInfo*)(((char*)pData) + 1))->Operate;
  517. aReturn.nReturn = E_ACCOUNT_ACCESSDENIED;
  518. aReturn.Account[0] = 0;
  519. pSocket->CustomSend(m_nClientID, s2c_gatewayverify, &aReturn);
  520. bRet = FALSE;
  521. bStopConn = TRUE;
  522. }
  523. else
  524. {
  525. bRet = ProRelayVerify(pConn, ((char*)pData) + 2, dwDataSize - 2);
  526. if (bRet)
  527. {
  528. StartAutoTime();
  529. pSocket->NotifyRelayLoginInfo(m_nGameID, m_nClientID, m_Address, m_ServerName);
  530. }
  531. else
  532. bStopConn = TRUE;
  533. }
  534. }
  535. else if (nFamily == pf_normal && nProtocol == c2s_gatewayinfo)
  536. {
  537. if (m_nGameID == 0)
  538. {
  539. bStopConn = TRUE;
  540. }
  541. else
  542. {
  543. bRet = ProRelayInfo(pConn, ((char*)pData) + 2, dwDataSize - 2);
  544. }
  545. }
  546. else if (nFamily == pf_normal && nProtocol == c2s_accountlogout) //unlock account
  547. {
  548. if (m_nGameID == 0)
  549. {
  550. bStopConn = TRUE;
  551. }
  552. else
  553. {
  554. bRet = ProAccountLogout(pConn, ((char*)pData) + 2, dwDataSize - 2);
  555. }
  556. }
  557. else if (nFamily == pf_normal && nProtocol == c2s_gamelogin) //freeze account
  558. {
  559. if (m_nGameID == 0)
  560. {
  561. bStopConn = TRUE;
  562. }
  563. else
  564. {
  565. bRet = ProGameLogin(pConn, ((char*)pData) + 2, dwDataSize - 2);
  566. }
  567. }
  568. else
  569. {
  570. if (m_nGameID > 0)
  571. {
  572. if (nFamily == pf_relay && nProtocol == relay_c2c_askwaydata)
  573. {
  574. bRet = ProRelayAskData(pConn, (const IBYTE*)pData, dwDataSize);
  575. }
  576. else if (nFamily == pf_gamemaster)
  577. {
  578. bRet = ProGMFamily(pConn, (const IBYTE*)pData, dwDataSize);
  579. }
  580. }
  581. else
  582. bStopConn = TRUE;
  583. }
  584. if (bStopConn)
  585. {
  586. KPISetEvent(m_hStop);
  587. }
  588. return bRet;
  589. }
  590. BOOL KGatewayDataProcess::ProRelayVerify(S3PDBConVBC* pConn, const IBYTE* lpData, const DWORD dwDataSize)
  591. {
  592. BOOL bRet = FALSE;
  593. if (NULL != lpData && dwDataSize == sizeof(KServerAccountUserLoginInfo))
  594. {
  595. KServerAccountUserLoginInfo* pAccInfo = (KServerAccountUserLoginInfo*)(lpData);
  596. if (pAccInfo->Version == ACCOUNT_CURRENT_VERSION &&
  597. pAccInfo->Type == ServerAccountUserLoginInfo)
  598. {
  599. KAccountUserReturn aReturn;
  600. aReturn.Size = sizeof(KAccountUserReturn);
  601. aReturn.Type = AccountUserReturn;
  602. aReturn.Operate = pAccInfo->Operate;
  603. memcpy(aReturn.Account, pAccInfo->Account, LOGIN_USER_ACCOUNT_MAX_LEN);
  604. DWORD nGameID = 0;
  605. aReturn.nReturn = S3PAccount::ServerLogin(pConn, pAccInfo->Account, pAccInfo->Password, m_Address, m_Port, pAccInfo->MacAddress, nGameID);
  606. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  607. in_addr ar;
  608. ar.s_addr = m_Address;
  609. if (aReturn.nReturn == ACTION_SUCCESS)
  610. {
  611. assert(nGameID > 0);
  612. if (pSocket->FindGatewayByID(nGameID) == NULL)
  613. {
  614. m_ServerName = pAccInfo->Account;
  615. m_nGameID = nGameID;
  616. bRet = TRUE;
  617. }
  618. else
  619. {
  620. aReturn.nReturn = E_ACCOUNT_EXIST;
  621. }
  622. }
  623. char szmac[15];
  624. sprintf(szmac, "%02X%02X-%02X%02X-%02X%02X", pAccInfo->MacAddress[0], pAccInfo->MacAddress[1], pAccInfo->MacAddress[2], pAccInfo->MacAddress[3], pAccInfo->MacAddress[4], pAccInfo->MacAddress[5]);
  625. szmac[14] = 0;
  626. if (bRet)
  627. gTrace("Relay %s(%s)%s: Verify OK !", m_ServerName.c_str(), inet_ntoa(ar), szmac);
  628. else
  629. {
  630. if (aReturn.nReturn == E_ACCOUNT_EXIST)
  631. gTrace("Relay %s(%s)%s: Already login !", m_ServerName.c_str(), inet_ntoa(ar), szmac);
  632. else if (aReturn.nReturn == E_ACCOUNT_OR_PASSWORD)
  633. gTrace("Relay %s(%s)%s: Name, Password !", m_ServerName.c_str(), inet_ntoa(ar), szmac);
  634. else if (aReturn.nReturn == E_ADDRESS_OR_PORT)
  635. gTrace("Relay %s(%s)%s: Address, Port !", m_ServerName.c_str(), inet_ntoa(ar), szmac);
  636. }
  637. pSocket->CustomSend(m_nClientID, s2c_gatewayverify, &aReturn);
  638. }
  639. else
  640. gTrace("Protocol %d data is error", c2s_gatewayverify);
  641. }
  642. else
  643. gTrace("Protocol %d data is error", c2s_gatewayverify);
  644. return bRet;
  645. }
  646. BOOL KGatewayDataProcess::ProRelayClose(S3PDBConVBC* pConn, const IBYTE* lpData, const DWORD dwDataSize)
  647. {
  648. BOOL bRet = FALSE;
  649. if (NULL != lpData && dwDataSize == sizeof(KAccountUser))
  650. {
  651. KAccountUser* pAccInfo = (KAccountUser*)(lpData);
  652. if (pAccInfo->Version == ACCOUNT_CURRENT_VERSION &&
  653. pAccInfo->Type == AccountUser)
  654. {
  655. S3PAccount::ServerLogout(pConn, pAccInfo->Operate, 0);
  656. bRet = TRUE;
  657. KPISetEvent(m_hClosed);
  658. }
  659. }
  660. return bRet;
  661. }
  662. BOOL KGatewayDataProcess::ProRelayInfo(S3PDBConVBC* pConn, const IBYTE* lpData, const DWORD dwDataSize)
  663. {
  664. BOOL bRet = FALSE;
  665. if (NULL != lpData && dwDataSize == sizeof(KServerInfo))
  666. {
  667. KServerInfo* pSerInfo = (KServerInfo*)(lpData);
  668. if (pSerInfo->Version == ACCOUNT_CURRENT_VERSION &&
  669. pSerInfo->Type == ServerInfo)
  670. {
  671. DWORD dValue = 0;
  672. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  673. unsigned long nGameID;
  674. if (pSerInfo->nServerType & server_OnlinePlayerCount)
  675. {
  676. nGameID = 0;
  677. pSocket->FindGatewayByServerName(pSerInfo->Account, nGameID);
  678. S3PAccount::GetAccountCount(pConn, nGameID, TRUE, dValue);
  679. }
  680. else if (pSerInfo->nServerType & server_RegisterCount)
  681. {
  682. //所有注册用户
  683. S3PAccount::GetAccountCount(pConn, 0, FALSE, dValue);
  684. }
  685. else if (pSerInfo->nServerType & server_PlayerWhere)
  686. {
  687. DWORD nID = 0;
  688. int iRet = S3PAccount::GetAccountGameID(pConn, pSerInfo->Account, nID);
  689. if (iRet == E_ACCOUNT_OR_PASSWORD)
  690. dValue = 0xFFFFFFFF;
  691. else if (iRet == ACTION_SUCCESS)
  692. {
  693. if (nID >= 0)
  694. {
  695. KGatewayDataProcess* p = pSocket->FindGatewayByID(nID);
  696. if (p)
  697. {
  698. dValue = p->m_Address;
  699. }
  700. }
  701. else
  702. dValue = 0;
  703. }
  704. }
  705. else if (pSerInfo->nServerType & server_PlayerWhereID)
  706. {
  707. DWORD nID = 0;
  708. int iRet = S3PAccount::GetAccountGameID(pConn, pSerInfo->Account, nID);
  709. if (iRet == E_ACCOUNT_OR_PASSWORD)
  710. dValue = 0xFFFFFFFF;
  711. else if (iRet == ACTION_SUCCESS)
  712. {
  713. if (nID >= 0)
  714. {
  715. KGatewayDataProcess* p = pSocket->FindGatewayByID(nID);
  716. if (p)
  717. {
  718. dValue = p->m_nClientID;
  719. }
  720. }
  721. else
  722. dValue = 0xFFFFFFFF;
  723. }
  724. }
  725. else if (pSerInfo->nServerType & server_GWRelayID)
  726. {
  727. if (pSocket->FindGatewayByServerName(pSerInfo->Account, nGameID))
  728. {
  729. if (nGameID >= 0)
  730. {
  731. KGatewayDataProcess* p = pSocket->FindGatewayByID(nGameID);
  732. if (p)
  733. {
  734. dValue = p->m_nClientID;
  735. }
  736. }
  737. else
  738. dValue = 0xFFFFFFFF;
  739. }
  740. }
  741. else
  742. assert(0);
  743. KServerInfo aReturn;
  744. aReturn.Size = sizeof(KServerInfo);
  745. aReturn.Type = ServerInfo;
  746. aReturn.Operate = 0;
  747. aReturn.Version = ACCOUNT_CURRENT_VERSION;
  748. strncpy(aReturn.Account, pSerInfo->Account, LOGIN_USER_ACCOUNT_MAX_LEN);
  749. aReturn.nServerType = pSerInfo->nServerType;
  750. aReturn.nValue = dValue;
  751. pSocket->CustomSend(m_nClientID, s2c_gatewayinfo, &aReturn);
  752. bRet = TRUE;
  753. }
  754. else
  755. gTrace("Protocol %d data is error", c2s_gatewayinfo);
  756. }
  757. else
  758. gTrace("Protocol %d data is error", c2s_gatewayinfo);
  759. return bRet;
  760. }
  761. BOOL KGatewayDataProcess::ProAccountLogout(S3PDBConVBC* pConn, const IBYTE* lpData, const DWORD dwDataSize)
  762. {
  763. BOOL bRet = FALSE;
  764. if (NULL != lpData && dwDataSize == sizeof(KAccountUserLogout))
  765. {
  766. KAccountUserLogout* pAccInfo = (KAccountUserLogout*)(lpData);
  767. if (pAccInfo->Version == ACCOUNT_CURRENT_VERSION &&
  768. pAccInfo->Type == AccountUserLogout)
  769. {
  770. KAccountUserReturn aReturn;
  771. aReturn.Size = sizeof(KAccountUserReturn);
  772. aReturn.Type = AccountUserReturn;
  773. aReturn.Operate = pAccInfo->Operate;
  774. memcpy(aReturn.Account, pAccInfo->Account, LOGIN_USER_ACCOUNT_MAX_LEN);
  775. aReturn.nReturn = S3PAccount::UnlockAccount(pConn, pAccInfo->Account);
  776. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  777. char* szDetail = NULL;
  778. in_addr ar;
  779. ar.s_addr = m_Address;
  780. if (aReturn.nReturn == ACTION_SUCCESS)
  781. {
  782. bRet = TRUE;
  783. szDetail = " Success !";
  784. }
  785. else
  786. {
  787. szDetail = " Failed !";
  788. }
  789. gTrace("Gateway %s(%s): User %s Unlock%s", m_ServerName.c_str(), inet_ntoa(ar), pAccInfo->Account, szDetail);
  790. pSocket->CustomSend(m_nClientID, s2c_accountlogout, &aReturn);
  791. }
  792. else
  793. gTrace("Protocol %d data is error", c2s_accountlogout);
  794. }
  795. else
  796. gTrace("Protocol %d data is error", c2s_accountlogout);
  797. return bRet;
  798. }
  799. BOOL KGatewayDataProcess::ProGameLogin(S3PDBConVBC* pConn, const IBYTE* lpData, const DWORD dwDataSize)
  800. {
  801. BOOL bRet = FALSE;
  802. if (NULL != lpData && dwDataSize == sizeof(KAccountUser))
  803. {
  804. KAccountUser* pAccInfo = (KAccountUser*)(lpData);
  805. if (pAccInfo->Version == ACCOUNT_CURRENT_VERSION &&
  806. pAccInfo->Type == AccountUser)
  807. {
  808. KAccountUserReturn aReturn;
  809. aReturn.Size = sizeof(KAccountUserReturn);
  810. aReturn.Type = AccountUserReturn;
  811. aReturn.Operate = pAccInfo->Operate;
  812. memcpy(aReturn.Account, pAccInfo->Account, LOGIN_USER_ACCOUNT_MAX_LEN);
  813. aReturn.nReturn = S3PAccount::FreezeAccount(pConn, pAccInfo->Account);
  814. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  815. char* szDetail = NULL;
  816. in_addr ar;
  817. ar.s_addr = m_Address;
  818. if (aReturn.nReturn == ACTION_SUCCESS)
  819. {
  820. bRet = TRUE;
  821. char szS[200];
  822. sprintf(szS, "GlobalExecute("dw KickOutAccount([[%s]])")", pAccInfo->Account);
  823. ExecuteAction(szS);//踢人
  824. gTrace("Account(%s) is KickOff!", pAccInfo->Account);
  825. szDetail = " Success !";
  826. }
  827. else
  828. {
  829. szDetail = " Failed !";
  830. }
  831. gTrace("Gateway %s(%s): User %s Freeze Account%s", m_ServerName.c_str(), inet_ntoa(ar), pAccInfo->Account, szDetail);
  832. pSocket->CustomSend(m_nClientID, s2c_gamelogin, &aReturn);
  833. }
  834. else
  835. gTrace("Protocol %d data is error", c2s_gamelogin);
  836. }
  837. else
  838. gTrace("Protocol %d data is error", c2s_gamelogin);
  839. return bRet;
  840. }
  841. BOOL KGatewayDataProcess::ProRelayIPData(const IBYTE* lpData, const DWORD dwDataSize)
  842. {
  843. BOOL bRet = FALSE;
  844. if (NULL != lpData && dwDataSize >= sizeof(RELAY_DATA))
  845. {
  846. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  847. RELAY_DATA* pIPData = (RELAY_DATA*)lpData;
  848. if (pIPData->routeDateLength + sizeof(RELAY_DATA) != dwDataSize)
  849. return FALSE;
  850. if (pIPData->nFromIP == 0) //刚进入Relay体系,填写nFromIP和nFromRelayID
  851. {
  852. pIPData->nFromIP = m_Address;
  853. pIPData->nFromRelayID = m_nClientID;
  854. }
  855. if (pIPData->nToIP == 0) //目的地已经到达,开始处理实际协议
  856. {
  857. char* pRelayPackage = (char*)(pIPData + 1);
  858. ProcessClientData(pRelayPackage, pIPData->routeDateLength);
  859. bRet = TRUE;
  860. }
  861. else if (pIPData->nToIP == pSocket->m_SelfAddress) //最后一个Relay
  862. {
  863. DWORD nClient = pIPData->nToRelayID;
  864. pIPData->nToIP = 0;
  865. pIPData->nToRelayID = 0;
  866. pSocket->SendData(nClient, pIPData, dwDataSize);
  867. bRet = TRUE;
  868. }
  869. else
  870. {
  871. DWORD nClient = 0;
  872. if (pSocket->FindGatewayClientByAddress(pIPData->nToIP, nClient))
  873. {
  874. pSocket->SendData(nClient, pIPData, dwDataSize);
  875. bRet = TRUE;
  876. }
  877. }
  878. }
  879. return bRet;
  880. }
  881. BOOL KGatewayDataProcess::ProRelayAskData(S3PDBConVBC* pConn, const IBYTE* lpData, const DWORD dwDataSize)
  882. {
  883. BOOL bRet = FALSE;
  884. if (NULL != lpData && dwDataSize >= sizeof(RELAY_ASKWAY_DATA))
  885. {
  886. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  887. RELAY_ASKWAY_DATA* pIPData = (RELAY_ASKWAY_DATA*)lpData;
  888. if (pIPData->routeDateLength + pIPData->wMethodDataLength + sizeof(RELAY_ASKWAY_DATA) != dwDataSize)
  889. return FALSE;
  890. if (pIPData->seekMethod == rm_account_id ||
  891. pIPData->seekMethod == rm_gm)
  892. {
  893. if (pIPData->nFromIP == 0) //刚进入Relay体系,填写nFromIP和nFromRelayID
  894. {
  895. pIPData->nFromIP = m_Address;
  896. pIPData->nFromRelayID = m_nClientID;
  897. }
  898. KGatewayDataProcess* p = NULL;
  899. if (pIPData->seekMethod == rm_account_id)
  900. {
  901. DWORD nGameID = 0;
  902. char name[33];
  903. strncpy(name, lpData + sizeof(RELAY_ASKWAY_DATA), 32);
  904. if (ACTION_SUCCESS == S3PAccount::GetAccountGameID(pConn, name, nGameID))
  905. p = pSocket->FindGatewayByID(nGameID);
  906. }
  907. else if (pIPData->seekMethod == rm_gm)
  908. {
  909. pSocket->BroadGMData(lpData, dwDataSize);
  910. bRet = TRUE;
  911. }
  912. if (p)
  913. {
  914. pSocket->SendData(p->m_nClientID, lpData, dwDataSize);
  915. bRet = TRUE;
  916. }
  917. }
  918. if (!bRet) //地址不可达,通知来源relay_s2c_loseway
  919. {
  920. size_t sizeLose = sizeof(RELAY_DATA) + dwDataSize;
  921. RELAY_DATA* pLoseData = (RELAY_DATA*)_alloca(sizeLose);
  922. pLoseData->ProtocolFamily = pIPData->ProtocolFamily;
  923. pLoseData->ProtocolID = relay_s2c_loseway;
  924. pLoseData->nToIP = pIPData->nFromIP;
  925. pLoseData->nToRelayID = pIPData->nFromRelayID;
  926. pLoseData->nFromIP = pSocket->m_SelfAddress;
  927. pLoseData->nFromRelayID = -1;
  928. pLoseData->routeDateLength = dwDataSize;
  929. memcpy(pLoseData + 1, pIPData, dwDataSize);
  930. pSocket->SendData(m_nClientID, pLoseData, sizeLose);
  931. }
  932. }
  933. return bRet;
  934. }
  935. BOOL KGatewayDataProcess::ProGMFamily(S3PDBConVBC* pConn, const IBYTE* lpData, const DWORD dwDataSize)
  936. {
  937. int nResult = ACTION_SUCCESS;
  938. switch(((GM_HEADER*)lpData)->ProtocolType)
  939. {
  940. case gm_c2s_execute:
  941. _ASSERT(0);
  942. break;
  943. case gm_c2s_disable:
  944. _ASSERT(0);
  945. break;
  946. case gm_c2s_enable:
  947. _ASSERT(0);
  948. break;
  949. case gm_c2s_tracking:
  950. _ASSERT(0);
  951. break;
  952. case gm_c2s_setrole:
  953. _ASSERT(0);
  954. break;
  955. case gm_c2s_getrole:
  956. _ASSERT(0);
  957. break;
  958. case gm_c2s_findplayer:
  959. _ASSERT(0);
  960. break;
  961. case gm_c2s_unlock:
  962. {
  963. DWORD nGameID = 0;
  964. S3PAccount::GetServerID(pConn, ((GM_UNLOCK_ACCOUNT*)lpData)->AccountName, nGameID);
  965. if (nGameID > 0)
  966. {
  967. nResult = S3PAccount::UnlockServer(pConn, nGameID);
  968. }
  969. }
  970. break;
  971. default:
  972. _ASSERT(0);
  973. break;
  974. }
  975. return (ACTION_SUCCESS == nResult);
  976. }
  977. S3PDBConVBC* KGatewayDataProcess::GetDB(DWORD nSleep)
  978. {
  979. if (!m_pConn)
  980. {
  981. S3PDBConnectionPool* pDB = S3PDBConnectionPool::Instance();
  982. if (nSleep)
  983. {
  984. while (m_pConn == NULL)
  985. {
  986. pDB->RemoveDBCon(&m_pConn);
  987. Sleep(nSleep);
  988. }
  989. }
  990. else
  991. pDB->RemoveDBCon(&m_pConn);
  992. }
  993. return m_pConn;
  994. }
  995. DWORD KGatewayDataProcess::Main(LPVOID lpParam)
  996. {
  997. assert(m_hStop);
  998. assert(m_pServer);
  999. DWORD dwRet = 0;
  1000. DWORD LastTime = GetTickCount();
  1001. S3PDBConnectionPool* pDB = S3PDBConnectionPool::Instance();
  1002. BOOL bValidID = CheckConnectAddress();
  1003. while (bValidID)
  1004. {
  1005. DWORD dwResult =
  1006. KPIWaitForSingleObject(m_hStop, 0);
  1007. if (dwResult == 1)
  1008. break;
  1009. else if (dwResult == 2)
  1010. {
  1011. size_t datalength = 0;
  1012. const void *pData = m_pServer->GetPackFromClient(m_nClientID, datalength);
  1013. AutoTime();
  1014. if (pData && 0 != datalength)
  1015. {
  1016. ProcessClientData(pData, datalength);
  1017. LastTime = GetTickCount();
  1018. }
  1019. else
  1020. {
  1021. if (GetTickCount() - LastTime >= 1000)
  1022. {
  1023. if (m_pConn)
  1024. {
  1025. if (pDB->ReturnDBCon(m_pConn))
  1026. m_pConn = NULL;
  1027. }
  1028. }
  1029. Sleep(1);
  1030. }
  1031. }
  1032. }
  1033. Close();
  1034. if (m_pConn)
  1035. {
  1036. if (pDB->ReturnDBCon(m_pConn))
  1037. m_pConn = NULL;
  1038. }
  1039. m_pServer->ShutdownClient(m_nClientID);
  1040. return dwRet;
  1041. }
  1042. HANDLE KGatewayDataProcess::Start(IServer* pServer)
  1043. {
  1044. assert(pServer);
  1045. if (NULL == m_pServer)
  1046. {
  1047. m_pServer = pServer;
  1048. pServer->AddRef();
  1049. }
  1050. return KThread::Start();
  1051. }
  1052. BOOL KGatewayDataProcess::Stop()
  1053. {
  1054. BOOL bRet = KThread::Stop();
  1055. if (bRet && m_pServer)
  1056. {
  1057. m_pServer->Release();
  1058. m_pServer = NULL;
  1059. }
  1060. return bRet;
  1061. }
  1062. BOOL KGatewayDataProcess::ProAutoTime(S3PDBConVBC* pConn)
  1063. {
  1064. BOOL bRet = FALSE;
  1065. DWORD dwMin = 0;
  1066. dwMin = 1800; //默认30分钟
  1067. char szMessage[128];
  1068. if (dwMin > 0)
  1069. {
  1070. AccountTimeList TimeList;
  1071. if (S3PAccount::GetAccountsTime(pConn, m_nGameID, dwMin, TimeList) == ACTION_SUCCESS)
  1072. {
  1073. AccountTimeList::iterator i = TimeList.begin();
  1074. while (i != TimeList.end())
  1075. {
  1076. if (i->nTime == 0) //踢人
  1077. {
  1078. char szS[200];
  1079. sprintf(szS, "GlobalExecute("dw KickOutAccount([[%s]])")", i->Account);
  1080. ExecuteAction(szS);//踢人
  1081. gTrace("Account(%s) is KickOff!", i->Account);
  1082. }
  1083. else //催促充值
  1084. {
  1085. int nLen = 0;
  1086. if (i->nTime >= 60)
  1087. nLen = sprintf(szMessage, "您在游戏中还可以停留%d分钟, 请赶快充值!", i->nTime / 60);
  1088. else
  1089. nLen = sprintf(szMessage, "您在游戏中还可以停留%d秒, 请赶快充值!", i->nTime);
  1090. SendSystemInfo(m_nClientID, i->Account, "GM", szMessage, nLen);
  1091. }
  1092. i++;
  1093. }
  1094. bRet = TRUE;
  1095. }
  1096. }
  1097. return bRet;
  1098. }
  1099. void KGatewayDataProcess::ExecuteAction(char* szAccount, char* szScript)
  1100. {
  1101. int nszLen = 0;
  1102. if (szScript)
  1103. nszLen = strlen(szScript);
  1104. GM_EXECUTE_COMMAND exe;
  1105. exe.ProtocolFamily = pf_gamemaster;
  1106. exe.ProtocolType = gm_c2s_execute;
  1107. strncpy(exe.AccountName, szAccount, LOGIN_USER_ACCOUNT_MAX_LEN);
  1108. exe.wLength = nszLen;
  1109. exe.wExecuteID = 1;
  1110. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  1111. pSocket->SendRelayData(m_nClientID, szAccount, &exe, sizeof(exe), szScript, nszLen);
  1112. }
  1113. void KGatewayDataProcess::ExecuteAction(char* szScript)
  1114. {
  1115. int nszLen = 0;
  1116. if (szScript)
  1117. nszLen = strlen(szScript);
  1118. GM_EXECUTE_COMMAND exe;
  1119. exe.ProtocolFamily = pf_gamemaster;
  1120. exe.ProtocolType = gm_c2s_execute;
  1121. strncpy(exe.AccountName, "GM", LOGIN_USER_ACCOUNT_MAX_LEN);
  1122. exe.wLength = nszLen;
  1123. exe.wExecuteID = 1;
  1124. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  1125. pSocket->SendRelayData(m_nClientID, &exe, sizeof(exe), szScript, nszLen);
  1126. }
  1127. void KGatewayDataProcess::SendSystemInfo(unsigned long uID, char* szAccount, char *lpszSendName, char *lpszSentence, int nSentenceLength)
  1128. {
  1129. size_t chatsize = 1 + sizeof(CHAT_CHANNELCHAT_SYNC) + nSentenceLength;
  1130. BYTE* pFamily = (BYTE*)_alloca(chatsize);
  1131. *pFamily = pf_chat;
  1132. CHAT_CHANNELCHAT_SYNC* pCccSync= (CHAT_CHANNELCHAT_SYNC*)(pFamily + 1);
  1133. pCccSync->ProtocolType = chat_channelchat;
  1134. pCccSync->wSize = chatsize - 1;
  1135. pCccSync->packageID = -1;
  1136. strncpy(pCccSync->someone, lpszSendName, _NAME_LEN - 1); // 可能需要根据玩家身份改动
  1137. pCccSync->channelid = -1;
  1138. pCccSync->sentlen = nSentenceLength;
  1139. memcpy(pCccSync + 1, lpszSentence, nSentenceLength);
  1140. S3PDBSocketPool* pSocket = S3PDBSocketPool::Instance();
  1141. pSocket->SendRelayData(uID, szAccount, pFamily, chatsize, NULL, 0);
  1142. }