Advertisement
Guest User

db.cpp

a guest
Nov 11th, 2023
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 38.30 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <sstream>
  3. #include "../../common/billing.h"
  4. #include "../../common/length.h"
  5.  
  6. #include "db.h"
  7.  
  8. #include "config.h"
  9. #include "desc_client.h"
  10. #include "desc_manager.h"
  11. #include "char.h"
  12. #include "char_manager.h"
  13. #include "item.h"
  14. #include "item_manager.h"
  15. #include "p2p.h"
  16. #include "matrix_card.h"
  17. #include "log.h"
  18. #include "login_data.h"
  19. #include "locale_service.h"
  20. #include "pcbang.h"
  21. #include "spam.h"
  22. #include "auth_brazil.h"
  23. #include "shutdown_manager.h"
  24. #include "../../libargon2/include/argon2.h"
  25.  
  26.  
  27. bool CheckPasspod(const char * account)
  28. {
  29. char szQuery[1024];
  30.  
  31. snprintf(szQuery, sizeof(szQuery), "SELECT ID FROM passpod WHERE Login='%s'", account);
  32. SQLMsg * pMsg = DBManager::instance().DirectQuery(szQuery);
  33.  
  34. if (!pMsg)
  35. {
  36. //fprintf(stderr, "cannot get the MATRIX\n");
  37. sys_log(0, "cannot get the PASSPOD");
  38. delete pMsg;
  39. return false;
  40. }
  41.  
  42. if (pMsg->Get()->uiNumRows == 0)
  43. {
  44. puts(szQuery);
  45. sys_log(0, "[PASSPOD]DirectQuery failed(%s)", szQuery);
  46.  
  47. delete pMsg;
  48. return false;
  49. }
  50.  
  51. delete pMsg;
  52.  
  53. return true;
  54. }
  55.  
  56.  
  57. DBManager::DBManager() : m_bIsConnect(false)
  58. {
  59. }
  60.  
  61. DBManager::~DBManager()
  62. {
  63. }
  64.  
  65. bool DBManager::Connect(const char * host, const int port, const char * user, const char * pwd, const char * db)
  66. {
  67. if (m_sql.Setup(host, user, pwd, db, g_stLocale.c_str(), false, port))
  68. m_bIsConnect = true;
  69.  
  70. if (!m_sql_direct.Setup(host, user, pwd, db, g_stLocale.c_str(), true, port))
  71. sys_err("cannot open direct sql connection to host %s", host);
  72.  
  73. if (m_bIsConnect && !g_bAuthServer)
  74. {
  75. LoadDBString();
  76. }
  77.  
  78. return m_bIsConnect;
  79. }
  80.  
  81. void DBManager::Query(const char * c_pszFormat, ...)
  82. {
  83. char szQuery[4096];
  84. va_list args;
  85.  
  86. va_start(args, c_pszFormat);
  87. vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
  88. va_end(args);
  89.  
  90. m_sql.AsyncQuery(szQuery);
  91. }
  92.  
  93. SQLMsg * DBManager::DirectQuery(const char * c_pszFormat, ...)
  94. {
  95. char szQuery[4096];
  96. va_list args;
  97.  
  98. va_start(args, c_pszFormat);
  99. vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
  100. va_end(args);
  101.  
  102. return m_sql_direct.DirectQuery(szQuery);
  103. }
  104.  
  105. bool DBManager::IsConnected()
  106. {
  107. return m_bIsConnect;
  108. }
  109.  
  110. void DBManager::ReturnQuery(int iType, DWORD dwIdent, void * pvData, const char * c_pszFormat, ...)
  111. {
  112. //sys_log(0, "ReturnQuery %s", c_pszQuery);
  113. char szQuery[4096];
  114. va_list args;
  115.  
  116. va_start(args, c_pszFormat);
  117. vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
  118. va_end(args);
  119.  
  120. CReturnQueryInfo * p = M2_NEW CReturnQueryInfo;
  121.  
  122. p->iQueryType = QUERY_TYPE_RETURN;
  123. p->iType = iType;
  124. p->dwIdent = dwIdent;
  125. p->pvData = pvData;
  126.  
  127. m_sql.ReturnQuery(szQuery, p);
  128. }
  129.  
  130. SQLMsg * DBManager::PopResult()
  131. {
  132. SQLMsg * p;
  133.  
  134. if (m_sql.PopResult(&p))
  135. return p;
  136.  
  137. return NULL;
  138. }
  139.  
  140. void DBManager::Process()
  141. {
  142. SQLMsg* pMsg = NULL;
  143.  
  144. while ((pMsg = PopResult()))
  145. {
  146. if( NULL != pMsg->pvUserData )
  147. {
  148. switch( reinterpret_cast<CQueryInfo*>(pMsg->pvUserData)->iQueryType )
  149. {
  150. case QUERY_TYPE_RETURN:
  151. AnalyzeReturnQuery(pMsg);
  152. break;
  153.  
  154. case QUERY_TYPE_FUNCTION:
  155. {
  156. CFuncQueryInfo* qi = reinterpret_cast<CFuncQueryInfo*>( pMsg->pvUserData );
  157. qi->f(pMsg);
  158. M2_DELETE(qi);
  159. }
  160. break;
  161.  
  162. case QUERY_TYPE_AFTER_FUNCTION:
  163. {
  164. CFuncAfterQueryInfo* qi = reinterpret_cast<CFuncAfterQueryInfo*>( pMsg->pvUserData );
  165. qi->f();
  166. M2_DELETE(qi);
  167. }
  168. break;
  169. }
  170. }
  171.  
  172. delete pMsg;
  173. }
  174. }
  175.  
  176. CLoginData * DBManager::GetLoginData(DWORD dwKey)
  177. {
  178. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(dwKey);
  179.  
  180. if (it == m_map_pkLoginData.end())
  181. return NULL;
  182.  
  183. return it->second;
  184. }
  185.  
  186. void DBManager::InsertLoginData(CLoginData * pkLD)
  187. {
  188. m_map_pkLoginData.insert(std::make_pair(pkLD->GetKey(), pkLD));
  189. }
  190.  
  191. void DBManager::DeleteLoginData(CLoginData * pkLD)
  192. {
  193. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(pkLD->GetKey());
  194.  
  195. if (it == m_map_pkLoginData.end())
  196. return;
  197.  
  198. sys_log(0, "DeleteLoginData %s %p", pkLD->GetLogin(), pkLD);
  199.  
  200. mapLDBilling.erase(pkLD->GetLogin());
  201.  
  202. M2_DELETE(it->second);
  203. m_map_pkLoginData.erase(it);
  204. }
  205.  
  206. void DBManager::SetBilling(DWORD dwKey, bool bOn, bool bSkipPush)
  207. {
  208. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(dwKey);
  209.  
  210. if (it == m_map_pkLoginData.end())
  211. {
  212. sys_err("cannot find login key %u", dwKey);
  213. return;
  214. }
  215.  
  216. CLoginData * ld = it->second;
  217.  
  218. itertype(mapLDBilling) it2 = mapLDBilling.find(ld->GetLogin());
  219.  
  220. if (it2 != mapLDBilling.end())
  221. if (it2->second != ld)
  222. DeleteLoginData(it2->second);
  223.  
  224. mapLDBilling.insert(std::make_pair(ld->GetLogin(), ld));
  225.  
  226. if (ld->IsBilling() && !bOn && !bSkipPush)
  227. PushBilling(ld);
  228.  
  229. SendLoginPing(ld->GetLogin());
  230. ld->SetBilling(bOn);
  231. }
  232.  
  233. void DBManager::PushBilling(CLoginData * pkLD)
  234. {
  235. TUseTime t;
  236.  
  237. t.dwUseSec = (get_dword_time() - pkLD->GetLogonTime()) / 1000;
  238.  
  239. if (t.dwUseSec <= 0)
  240. return;
  241.  
  242. pkLD->SetLogonTime();
  243. long lRemainSecs = pkLD->GetRemainSecs() - t.dwUseSec;
  244. pkLD->SetRemainSecs(MAX(0, lRemainSecs));
  245.  
  246. t.dwLoginKey = pkLD->GetKey();
  247. t.bBillType = pkLD->GetBillType();
  248.  
  249. sys_log(0, "BILLING: PUSH %s %u type %u", pkLD->GetLogin(), t.dwUseSec, t.bBillType);
  250.  
  251. if (t.bBillType == BILLING_IP_FREE || t.bBillType == BILLING_IP_TIME || t.bBillType == BILLING_IP_DAY)
  252. snprintf(t.szLogin, sizeof(t.szLogin), "%u", pkLD->GetBillID());
  253. else
  254. strlcpy(t.szLogin, pkLD->GetLogin(), sizeof(t.szLogin));
  255.  
  256. strlcpy(t.szIP, pkLD->GetIP(), sizeof(t.szIP));
  257.  
  258. m_vec_kUseTime.push_back(t);
  259. }
  260.  
  261. void DBManager::FlushBilling(bool bForce)
  262. {
  263. if (bForce)
  264. {
  265. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.begin();
  266.  
  267. while (it != m_map_pkLoginData.end())
  268. {
  269. CLoginData * pkLD = (it++)->second;
  270.  
  271. if (pkLD->IsBilling())
  272. PushBilling(pkLD);
  273. }
  274. }
  275.  
  276. if (!m_vec_kUseTime.empty())
  277. {
  278. DWORD dwCount = 0;
  279.  
  280. std::vector<TUseTime>::iterator it = m_vec_kUseTime.begin();
  281.  
  282. while (it != m_vec_kUseTime.end())
  283. {
  284. TUseTime * p = &(*(it++));
  285.  
  286. // DISABLE_OLD_BILLING_CODE
  287. if (!g_bBilling)
  288. {
  289. ++dwCount;
  290. continue;
  291. }
  292.  
  293. Query("INSERT GameTimeLog (login, type, logon_time, logout_time, use_time, ip, server) "
  294. "VALUES('%s', %u, DATE_SUB(NOW(), INTERVAL %u SECOND), NOW(), %u, '%s', '%s')",
  295. p->szLogin, p->bBillType, p->dwUseSec, p->dwUseSec, p->szIP, g_stHostname.c_str());
  296. // DISABLE_OLD_BILLING_CODE_END
  297.  
  298. switch (p->bBillType)
  299. {
  300. case BILLING_FREE:
  301. case BILLING_IP_FREE:
  302. break;
  303.  
  304. case BILLING_DAY:
  305. {
  306. if (!bForce)
  307. {
  308. TUseTime * pInfo = M2_NEW TUseTime;
  309. memcpy(pInfo, p, sizeof(TUseTime));
  310. ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
  311. "SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTime WHERE UserID='%s'", p->szLogin);
  312. }
  313. }
  314. break;
  315.  
  316. case BILLING_TIME:
  317. {
  318. Query("UPDATE GameTime SET LimitTime=LimitTime-%u WHERE UserID='%s'", p->dwUseSec, p->szLogin);
  319.  
  320. if (!bForce)
  321. {
  322. TUseTime * pInfo = M2_NEW TUseTime;
  323. memcpy(pInfo, p, sizeof(TUseTime));
  324. ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
  325. "SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTime WHERE UserID='%s'", p->szLogin);
  326. }
  327. }
  328. break;
  329.  
  330. case BILLING_IP_DAY:
  331. {
  332. if (!bForce)
  333. {
  334. TUseTime * pInfo = M2_NEW TUseTime;
  335. memcpy(pInfo, p, sizeof(TUseTime));
  336. ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
  337. "SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTimeIP WHERE ipid=%s", p->szLogin);
  338. }
  339. }
  340. break;
  341.  
  342. case BILLING_IP_TIME:
  343. {
  344. Query("UPDATE GameTimeIP SET LimitTime=LimitTime-%u WHERE ipid=%s", p->dwUseSec, p->szLogin);
  345.  
  346. if (!bForce)
  347. {
  348. TUseTime * pInfo = M2_NEW TUseTime;
  349. memcpy(pInfo, p, sizeof(TUseTime));
  350. ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
  351. "SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTimeIP WHERE ipid=%s", p->szLogin);
  352. }
  353. }
  354. break;
  355. }
  356.  
  357. if (!bForce && ++dwCount >= 1000)
  358. break;
  359. }
  360.  
  361. if (dwCount < m_vec_kUseTime.size())
  362. {
  363. int nNewSize = m_vec_kUseTime.size() - dwCount;
  364. memcpy(&m_vec_kUseTime[0], &m_vec_kUseTime[dwCount], sizeof(TUseTime) * nNewSize);
  365. m_vec_kUseTime.resize(nNewSize);
  366. }
  367. else
  368. m_vec_kUseTime.clear();
  369.  
  370. sys_log(0, "FLUSH_USE_TIME: count %u", dwCount);
  371. }
  372.  
  373. if (m_vec_kUseTime.size() < 10240)
  374. {
  375. DWORD dwCurTime = get_dword_time();
  376.  
  377. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.begin();
  378.  
  379. while (it != m_map_pkLoginData.end())
  380. {
  381. CLoginData * pkLD = (it++)->second;
  382.  
  383. if (!pkLD->IsBilling())
  384. continue;
  385.  
  386. switch (pkLD->GetBillType())
  387. {
  388. case BILLING_IP_FREE:
  389. case BILLING_FREE:
  390. break;
  391.  
  392. case BILLING_IP_DAY:
  393. case BILLING_DAY:
  394. case BILLING_IP_TIME:
  395. case BILLING_TIME:
  396. if (pkLD->GetRemainSecs() < 0)
  397. {
  398. DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
  399.  
  400. if (dwSecsConnected % 10 == 0)
  401. SendBillingExpire(pkLD->GetLogin(), BILLING_DAY, 0, pkLD);
  402. }
  403. else if (pkLD->GetRemainSecs() <= 600) // if remain seconds lower than 10 minutes
  404. {
  405. DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
  406.  
  407. if (dwSecsConnected >= 60) // 60 second cycle
  408. {
  409. sys_log(0, "BILLING 1 %s remain %d connected secs %u",
  410. pkLD->GetLogin(), pkLD->GetRemainSecs(), dwSecsConnected);
  411. PushBilling(pkLD);
  412. }
  413. }
  414. else
  415. {
  416. DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
  417.  
  418. if (dwSecsConnected > (DWORD) (pkLD->GetRemainSecs() - 600) || dwSecsConnected >= 600)
  419. {
  420. sys_log(0, "BILLING 2 %s remain %d connected secs %u",
  421. pkLD->GetLogin(), pkLD->GetRemainSecs(), dwSecsConnected);
  422. PushBilling(pkLD);
  423. }
  424. }
  425. break;
  426. }
  427. }
  428. }
  429.  
  430. }
  431.  
  432. void DBManager::CheckBilling()
  433. {
  434. std::vector<DWORD> vec;
  435. vec.push_back(0);
  436.  
  437. //sys_log(0, "CheckBilling: map size %d", m_map_pkLoginData.size());
  438.  
  439. itertype(m_map_pkLoginData) it = m_map_pkLoginData.begin();
  440.  
  441. while (it != m_map_pkLoginData.end())
  442. {
  443. CLoginData * pkLD = (it++)->second;
  444.  
  445. if (pkLD->IsBilling())
  446. {
  447. sys_log(0, "BILLING: CHECK %u", pkLD->GetKey());
  448. vec.push_back(pkLD->GetKey());
  449. }
  450. }
  451.  
  452. vec[0] = vec.size() - 1;
  453. db_clientdesc->DBPacket(HEADER_GD_BILLING_CHECK, 0, &vec[0], sizeof(DWORD) * vec.size());
  454. }
  455.  
  456. void DBManager::SendLoginPing(const char * c_pszLogin)
  457. {
  458. TPacketGGLoginPing ptog;
  459.  
  460. ptog.bHeader = HEADER_GG_LOGIN_PING;
  461. strlcpy(ptog.szLogin, c_pszLogin, sizeof(ptog.szLogin));
  462.  
  463. if (!g_pkAuthMasterDesc) // If I am master, broadcast to others
  464. {
  465. P2P_MANAGER::instance().Send(&ptog, sizeof(TPacketGGLoginPing));
  466. }
  467. else // If I am slave send login ping to master
  468. {
  469. g_pkAuthMasterDesc->Packet(&ptog, sizeof(TPacketGGLoginPing));
  470. }
  471. }
  472.  
  473. void DBManager::SendAuthLogin(LPDESC d)
  474. {
  475. const TAccountTable & r = d->GetAccountTable();
  476.  
  477. CLoginData * pkLD = GetLoginData(d->GetLoginKey());
  478.  
  479. if (!pkLD)
  480. return;
  481.  
  482. TPacketGDAuthLogin ptod;
  483. ptod.dwID = r.id;
  484.  
  485. trim_and_lower(r.login, ptod.szLogin, sizeof(ptod.szLogin));
  486. strlcpy(ptod.szSocialID, r.social_id, sizeof(ptod.szSocialID));
  487. ptod.dwLoginKey = d->GetLoginKey();
  488. ptod.bBillType = pkLD->GetBillType();
  489. ptod.dwBillID = pkLD->GetBillID();
  490. #ifdef __MULTI_LANGUAGE_SYSTEM__
  491. ptod.bLanguage = r.bLanguage;
  492. #endif
  493. thecore_memcpy(ptod.iPremiumTimes, pkLD->GetPremiumPtr(), sizeof(ptod.iPremiumTimes));
  494. thecore_memcpy(&ptod.adwClientKey, pkLD->GetClientKey(), sizeof(DWORD) * 4);
  495.  
  496. db_clientdesc->DBPacket(HEADER_GD_AUTH_LOGIN, d->GetHandle(), &ptod, sizeof(TPacketGDAuthLogin));
  497. #ifdef __MULTI_LANGUAGE_SYSTEM__
  498. sys_log(0, "SendAuthLogin %s language %d key %u", ptod.szLogin, ptod.bLanguage, ptod.dwID);
  499. #else
  500. sys_log(0, "SendAuthLogin %s key %u", ptod.szLogin, ptod.dwID);
  501. #endif
  502.  
  503. SendLoginPing(r.login);
  504. }
  505.  
  506. void DBManager::LoginPrepare(BYTE bBillType, DWORD dwBillID, long lRemainSecs, LPDESC d, DWORD * pdwClientKey, int * paiPremiumTimes)
  507. {
  508. const TAccountTable & r = d->GetAccountTable();
  509.  
  510. CLoginData * pkLD = M2_NEW CLoginData;
  511.  
  512. pkLD->SetKey(d->GetLoginKey());
  513. pkLD->SetLogin(r.login);
  514. pkLD->SetBillType(bBillType);
  515. pkLD->SetBillID(dwBillID);
  516. pkLD->SetRemainSecs(lRemainSecs);
  517. pkLD->SetIP(d->GetHostName());
  518. pkLD->SetClientKey(pdwClientKey);
  519.  
  520. if (paiPremiumTimes)
  521. pkLD->SetPremium(paiPremiumTimes);
  522.  
  523. InsertLoginData(pkLD);
  524.  
  525. if (*d->GetMatrixCode())
  526. {
  527. unsigned long rows = 0, cols = 0;
  528. MatrixCardRndCoordinate(rows, cols);
  529.  
  530. d->SetMatrixCardRowsAndColumns(rows, cols);
  531.  
  532. TPacketGCMatrixCard pm;
  533.  
  534. pm.bHeader = HEADER_GC_MATRIX_CARD;
  535. pm.dwRows = rows;
  536. pm.dwCols = cols;
  537.  
  538. d->Packet(&pm, sizeof(TPacketGCMatrixCard));
  539.  
  540. sys_log(0, "MATRIX_QUERY: %s %c%d %c%d %c%d %c%d %s",
  541. r.login,
  542. MATRIX_CARD_ROW(rows, 0) + 'A',
  543. MATRIX_CARD_COL(cols, 0) + 1,
  544. MATRIX_CARD_ROW(rows, 1) + 'A',
  545. MATRIX_CARD_COL(cols, 1) + 1,
  546. MATRIX_CARD_ROW(rows, 2) + 'A',
  547. MATRIX_CARD_COL(cols, 2) + 1,
  548. MATRIX_CARD_ROW(rows, 3) + 'A',
  549. MATRIX_CARD_COL(cols, 3) + 1,
  550. d->GetMatrixCode());
  551. }
  552. else
  553. {
  554. #ifdef ENABLE_PASSPOD_FEATURE // @warme006
  555. {
  556. if (!g_bNoPasspod)
  557. {
  558. if (CheckPasspod(r.login))
  559. {
  560. BYTE id = HEADER_GC_REQUEST_PASSPOD;
  561. d->Packet(&id, sizeof(BYTE));
  562. sys_log(0, "%s request passpod", r.login);
  563. }
  564. else
  565. {
  566. SendAuthLogin(d);
  567.  
  568. }
  569. }
  570. else
  571. {
  572. SendAuthLogin(d);
  573. }
  574. }
  575. #else
  576. SendAuthLogin(d);
  577. #endif
  578. }
  579. }
  580.  
  581. bool GetGameTimeIP(MYSQL_RES * pRes, BYTE & bBillType, DWORD & dwBillID, int & seconds, const char * c_pszIP)
  582. {
  583. if (!pRes)
  584. return true;
  585.  
  586. MYSQL_ROW row = mysql_fetch_row(pRes);
  587. int col = 0;
  588.  
  589. str_to_number(dwBillID, row[col++]);
  590.  
  591. int ip_start = 0;
  592. str_to_number(ip_start, row[col++]);
  593.  
  594. int ip_end = 0;
  595. str_to_number(ip_end, row[col++]);
  596.  
  597. int type = 0;
  598. str_to_number(type, row[col++]);
  599.  
  600. str_to_number(seconds, row[col++]);
  601.  
  602. int day_seconds = 0;
  603. str_to_number(day_seconds, row[col++]);
  604.  
  605. char szIP[MAX_HOST_LENGTH + 1];
  606. strlcpy(szIP, c_pszIP, sizeof(szIP));
  607.  
  608. char * p = strrchr(szIP, '.');
  609. ++p;
  610.  
  611. int ip_postfix = 0;
  612. str_to_number(ip_postfix, p);
  613. int valid_ip = false;
  614.  
  615. if (ip_start <= ip_postfix && ip_end >= ip_postfix)
  616. valid_ip = true;
  617.  
  618. bBillType = BILLING_NONE;
  619.  
  620. if (valid_ip)
  621. {
  622. if (type == -1)
  623. return false;
  624.  
  625. if (type == 0)
  626. bBillType = BILLING_IP_FREE;
  627. else if (day_seconds > 0)
  628. {
  629. bBillType = BILLING_IP_DAY;
  630. seconds = day_seconds;
  631. }
  632. else if (seconds > 0)
  633. bBillType = BILLING_IP_TIME;
  634. }
  635.  
  636. return true;
  637. }
  638.  
  639. bool GetGameTime(MYSQL_RES * pRes, BYTE & bBillType, int & seconds)
  640. {
  641. if (!pRes)
  642. return true;
  643.  
  644. MYSQL_ROW row = mysql_fetch_row(pRes);
  645. sys_log(1, "GetGameTime %p %p %p", row[0], row[1], row[2]);
  646.  
  647. int type = 0;
  648. str_to_number(type, row[0]);
  649. str_to_number(seconds, row[1]);
  650. int day_seconds = 0;
  651. str_to_number(day_seconds, row[2]);
  652. bBillType = BILLING_NONE;
  653.  
  654. if (type == -1)
  655. return false;
  656. else if (type == 0)
  657. bBillType = BILLING_FREE;
  658. else if (day_seconds > 0)
  659. {
  660. bBillType = BILLING_DAY;
  661. seconds = day_seconds;
  662. }
  663. else if (seconds > 0)
  664. bBillType = BILLING_TIME;
  665.  
  666. if (!g_bBilling)
  667. bBillType = BILLING_FREE;
  668.  
  669. return true;
  670. }
  671.  
  672. void SendBillingExpire(const char * c_pszLogin, BYTE bBillType, int iSecs, CLoginData * pkLD)
  673. {
  674. TPacketBillingExpire ptod;
  675.  
  676. strlcpy(ptod.szLogin, c_pszLogin, sizeof(ptod.szLogin));
  677. ptod.bBillType = bBillType;
  678. ptod.dwRemainSeconds = MAX(0, iSecs);
  679. db_clientdesc->DBPacket(HEADER_GD_BILLING_EXPIRE, 0, &ptod, sizeof(TPacketBillingExpire));
  680. sys_log(0, "BILLING: EXPIRE %s type %d sec %d ptr %p", c_pszLogin, bBillType, iSecs, pkLD);
  681. }
  682.  
  683. void DBManager::AnalyzeReturnQuery(SQLMsg * pMsg)
  684. {
  685. CReturnQueryInfo * qi = (CReturnQueryInfo *) pMsg->pvUserData;
  686.  
  687. switch (qi->iType)
  688. {
  689. case QID_AUTH_LOGIN:
  690. {
  691. TPacketCGLogin3 * pinfo = (TPacketCGLogin3 *) qi->pvData;
  692. LPDESC d = DESC_MANAGER::instance().FindByLoginKey(qi->dwIdent);
  693.  
  694. if (!d)
  695. {
  696. M2_DELETE(pinfo);
  697. break;
  698. }
  699.  
  700. d->SetLogin(pinfo->login);
  701.  
  702. sys_log(0, "QID_AUTH_LOGIN: START %u %p", qi->dwIdent, get_pointer(d));
  703.  
  704. if (pMsg->Get()->uiNumRows == 0)
  705. {
  706. #ifdef ENABLE_BRAZIL_AUTH_FEATURE // @warme006
  707. {
  708.  
  709. // @fixme138 1. PASSWORD('%s') -> %s 2. pinfo->passwd wrapped inside Argon2PasswordHash(%s).c_str()
  710. ReturnQuery(QID_BRAZIL_CREATE_ID, qi->dwIdent, pinfo,
  711. "INSERT INTO account(login, password, social_id, create_time) "
  712. "VALUES('%s', '%s', '0000000', NOW()) ;",
  713. pinfo->login, Argon2PasswordHash(pinfo->passwd).c_str());
  714.  
  715. sys_log(0, "[AUTH_BRAZIL] : Create A new AccountID From OnGame");
  716. }
  717. #else
  718. {
  719. sys_log(0, " NOID");
  720. LoginFailure(d, "NOID");
  721. M2_DELETE(pinfo);
  722. }
  723. #endif
  724. }
  725. else
  726. {
  727. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  728. int col = 0;
  729.  
  730. // PASSWORD('%s'), password, securitycode, social_id, id, status
  731. char szEncrytPassword[EArgon2::HASH_LENGHT * 2 + 1] = {0, };
  732. char szPassword[EArgon2::HASH_LENGHT * 2 + 1] = {0, };
  733. char szMatrixCode[MATRIX_CODE_MAX_LEN + 1] = {0, };
  734. char szSocialID[SOCIAL_ID_MAX_LEN + 1] = {0, };
  735. char szStatus[ACCOUNT_STATUS_MAX_LEN + 1] = {0, };
  736. DWORD dwID = 0;
  737.  
  738. #ifdef __MULTI_LANGUAGE_SYSTEM__
  739. BYTE bLanguage = LOCALE_DEFAULT;
  740. #endif
  741. if (!row[col])
  742. {
  743. sys_err("error column %d", col);
  744. M2_DELETE(pinfo);
  745. break;
  746. }
  747.  
  748. strlcpy(szEncrytPassword, row[col++], sizeof(szEncrytPassword));
  749.  
  750. if (!row[col])
  751. {
  752. sys_err("error column %d", col);
  753. M2_DELETE(pinfo);
  754. break;
  755. }
  756.  
  757. strlcpy(szPassword, row[col++], sizeof(szPassword));
  758.  
  759. if (!row[col])
  760. {
  761. *szMatrixCode = '\0';
  762. col++;
  763. }
  764. else
  765. {
  766. strlcpy(szMatrixCode, row[col++], sizeof(szMatrixCode));
  767. }
  768.  
  769. if (!row[col])
  770. {
  771. sys_err("error column %d", col);
  772. M2_DELETE(pinfo);
  773. break;
  774. }
  775.  
  776. strlcpy(szSocialID, row[col++], sizeof(szSocialID));
  777.  
  778. if (!row[col])
  779. {
  780. sys_err("error column %d", col);
  781. M2_DELETE(pinfo);
  782. break;
  783. }
  784.  
  785. str_to_number(dwID, row[col++]);
  786.  
  787. if (!row[col])
  788. {
  789. sys_err("error column %d", col);
  790. M2_DELETE(pinfo);
  791. break;
  792. }
  793.  
  794. strlcpy(szStatus, row[col++], sizeof(szStatus));
  795.  
  796. #ifdef __MULTI_LANGUAGE_SYSTEM__
  797. if (!row[col])
  798. {
  799. sys_err("error column %d", col);
  800. M2_DELETE(pinfo);
  801. break;
  802. }
  803. str_to_number(bLanguage, row[col++]);
  804. #endif
  805. BYTE bNotAvail = 0;
  806. str_to_number(bNotAvail, row[col++]);
  807.  
  808. int aiPremiumTimes[PREMIUM_MAX_NUM];
  809. memset(&aiPremiumTimes, 0, sizeof(aiPremiumTimes));
  810.  
  811. char szCreateDate[256] = "00000000";
  812.  
  813. {
  814. str_to_number(aiPremiumTimes[PREMIUM_EXP], row[col++]);
  815. str_to_number(aiPremiumTimes[PREMIUM_ITEM], row[col++]);
  816. str_to_number(aiPremiumTimes[PREMIUM_SAFEBOX], row[col++]);
  817. str_to_number(aiPremiumTimes[PREMIUM_AUTOLOOT], row[col++]);
  818. str_to_number(aiPremiumTimes[PREMIUM_FISH_MIND], row[col++]);
  819. str_to_number(aiPremiumTimes[PREMIUM_MARRIAGE_FAST], row[col++]);
  820. str_to_number(aiPremiumTimes[PREMIUM_GOLD], row[col++]);
  821.  
  822. {
  823. long retValue = 0;
  824. str_to_number(retValue, row[col]);
  825.  
  826. time_t create_time = retValue;
  827. struct tm * tm1;
  828. tm1 = localtime(&create_time);
  829. strftime(szCreateDate, 255, "%Y%m%d", tm1);
  830.  
  831. sys_log(0, "Create_Time %d %s", retValue, szCreateDate);
  832. sys_log(0, "Block Time %d ", strncmp(szCreateDate, g_stBlockDate.c_str(), 8));
  833. }
  834. }
  835.  
  836. int nPasswordDiff = strcmp(szEncrytPassword, szPassword);
  837.  
  838.  
  839. if (openid_server)
  840. {
  841. nPasswordDiff = 0;
  842. }
  843.  
  844. if (nPasswordDiff)
  845. {
  846. LoginFailure(d, "WRONGPWD");
  847. sys_log(0, " WRONGPWD");
  848. M2_DELETE(pinfo);
  849. }
  850. else if (bNotAvail)
  851. {
  852. LoginFailure(d, "NOTAVAIL");
  853. sys_log(0, " NOTAVAIL");
  854. M2_DELETE(pinfo);
  855. }
  856. else if (DESC_MANAGER::instance().FindByLoginName(pinfo->login))
  857. {
  858. LoginFailure(d, "ALREADY");
  859. sys_log(0, " ALREADY");
  860. M2_DELETE(pinfo);
  861. }
  862. else if(!CShutdownManager::Instance().CheckCorrectSocialID(szSocialID) && !test_server)
  863. {
  864. LoginFailure(d, "BADSCLID");
  865. sys_log(0, " BADSCLID");
  866. M2_DELETE(pinfo);
  867. }
  868. else if(CShutdownManager::Instance().CheckShutdownAge(szSocialID) && CShutdownManager::Instance().CheckShutdownTime())
  869. {
  870. LoginFailure(d, "AGELIMIT");
  871. sys_log(0, " AGELIMIT");
  872. M2_DELETE(pinfo);
  873. }
  874. else if (strcmp(szStatus, "OK"))
  875. {
  876. LoginFailure(d, szStatus);
  877. sys_log(0, " STATUS: %s", szStatus);
  878. M2_DELETE(pinfo);
  879. }
  880. #ifdef __MULTI_LANGUAGE_SYSTEM__
  881. else if (pinfo->bLanguage >= LOCALE_MAX_NUM)
  882. {
  883. LoginFailure(d, "INVLANG");
  884. sys_log(0, "Invalid language selected.");
  885. M2_DELETE(pinfo);
  886. }
  887. else if (!pinfo->bLanguage)
  888. {
  889. LoginFailure(d, "NOLANG");
  890. sys_log(0, "No language selected.");
  891. M2_DELETE(pinfo);
  892. }
  893. #endif
  894. else
  895. {
  896. if (LC_IsEurope())
  897. {
  898. if (strncmp(szCreateDate, g_stBlockDate.c_str(), 8) >= 0)
  899. {
  900. LoginFailure(d, "BLKLOGIN");
  901. sys_log(0, " BLKLOGIN");
  902. M2_DELETE(pinfo);
  903. break;
  904. }
  905.  
  906. char szQuery[1024];
  907. #ifdef __MULTI_LANGUAGE_SYSTEM__
  908. snprintf(szQuery, sizeof(szQuery), "UPDATE account SET last_play=NOW(), language=%u WHERE id=%u", pinfo->bLanguage, dwID);
  909. #else
  910. snprintf(szQuery, sizeof(szQuery), "UPDATE account SET last_play=NOW() WHERE id=%u", dwID);
  911. #endif
  912. std::auto_ptr<SQLMsg> msg( DBManager::instance().DirectQuery(szQuery) );
  913. }
  914.  
  915. TAccountTable & r = d->GetAccountTable();
  916.  
  917. r.id = dwID;
  918. trim_and_lower(pinfo->login, r.login, sizeof(r.login));
  919. strlcpy(r.passwd, pinfo->passwd, sizeof(r.passwd));
  920. strlcpy(r.social_id, szSocialID, sizeof(r.social_id));
  921. #ifdef __MULTI_LANGUAGE_SYSTEM__
  922. r.bLanguage = pinfo->bLanguage; // bLanguage;
  923. #endif
  924. DESC_MANAGER::instance().ConnectAccount(r.login, d);
  925.  
  926. d->SetMatrixCode(szMatrixCode);
  927.  
  928. if (!g_bBilling)
  929. {
  930. LoginPrepare(BILLING_FREE, 0, 0, d, pinfo->adwClientKey, aiPremiumTimes);
  931. M2_DELETE(pinfo);
  932. break;
  933. }
  934.  
  935. sys_log(0, "QID_AUTH_LOGIN: SUCCESS %s", pinfo->login);
  936. }
  937. }
  938. }
  939. break;
  940.  
  941. case QID_BILLING_GET_TIME:
  942. {
  943. TPacketCGLogin3 * pinfo = (TPacketCGLogin3 *) qi->pvData;
  944. LPDESC d = DESC_MANAGER::instance().FindByLoginKey(qi->dwIdent);
  945.  
  946. sys_log(0, "QID_BILLING_GET_TIME: START ident %u d %p", qi->dwIdent, get_pointer(d));
  947.  
  948. if (d)
  949. {
  950. if (pMsg->Get()->uiNumRows == 0)
  951. {
  952. if (g_bBilling)
  953. LoginFailure(d, "NOBILL");
  954. else
  955. LoginPrepare(BILLING_FREE, 0, 0, d, pinfo->adwClientKey);
  956. }
  957. else
  958. {
  959. int seconds = 0;
  960. BYTE bBillType = BILLING_NONE;
  961.  
  962. if (!GetGameTime(pMsg->Get()->pSQLResult, bBillType, seconds))
  963. {
  964. sys_log(0, "QID_BILLING_GET_TIME: BLOCK");
  965. LoginFailure(d, "BLOCK");
  966. }
  967. else if (bBillType == BILLING_NONE)
  968. {
  969. LoginFailure(d, "NOBILL");
  970. sys_log(0, "QID_BILLING_GET_TIME: NO TIME");
  971. }
  972. else
  973. {
  974. LoginPrepare(bBillType, 0, seconds, d, pinfo->adwClientKey);
  975. sys_log(0, "QID_BILLING_GET_TIME: SUCCESS");
  976. }
  977. }
  978. }
  979. M2_DELETE(pinfo);
  980. }
  981. break;
  982.  
  983. case QID_BILLING_CHECK:
  984. {
  985. TUseTime * pinfo = (TUseTime *) qi->pvData;
  986. int iRemainSecs = 0;
  987.  
  988. CLoginData * pkLD = NULL;
  989.  
  990. if (pMsg->Get()->uiNumRows > 0)
  991. {
  992. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  993.  
  994. int iLimitDt = 0;
  995. str_to_number(iLimitDt, row[0]);
  996.  
  997. int iLimitTime = 0;
  998. str_to_number(iLimitTime, row[1]);
  999.  
  1000. pkLD = GetLoginData(pinfo->dwLoginKey);
  1001.  
  1002. if (pkLD)
  1003. {
  1004. switch (pkLD->GetBillType())
  1005. {
  1006. case BILLING_TIME:
  1007. if (iLimitTime <= 600 && iLimitDt > 0)
  1008. {
  1009. iRemainSecs = iLimitDt;
  1010. pkLD->SetBillType(BILLING_DAY);
  1011. pinfo->bBillType = BILLING_DAY;
  1012. }
  1013. else
  1014. iRemainSecs = iLimitTime;
  1015. break;
  1016.  
  1017. case BILLING_IP_TIME:
  1018. if (iLimitTime <= 600 && iLimitDt > 0)
  1019. {
  1020. iRemainSecs = iLimitDt;
  1021. pkLD->SetBillType(BILLING_IP_DAY);
  1022. pinfo->bBillType = BILLING_IP_DAY;
  1023. }
  1024. else
  1025. iRemainSecs = iLimitTime;
  1026. break;
  1027.  
  1028. case BILLING_DAY:
  1029. case BILLING_IP_DAY:
  1030. iRemainSecs = iLimitDt;
  1031. break;
  1032. }
  1033.  
  1034. pkLD->SetRemainSecs(iRemainSecs);
  1035. }
  1036. }
  1037.  
  1038. SendBillingExpire(pinfo->szLogin, pinfo->bBillType, MAX(0, iRemainSecs), pkLD);
  1039. M2_DELETE(pinfo);
  1040. }
  1041. break;
  1042.  
  1043. case QID_SAFEBOX_SIZE:
  1044. {
  1045. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(qi->dwIdent);
  1046.  
  1047. if (ch)
  1048. {
  1049. if (pMsg->Get()->uiNumRows > 0)
  1050. {
  1051. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  1052. int size = 0;
  1053. str_to_number(size, row[0]);
  1054. ch->SetSafeboxSize(SAFEBOX_PAGE_SIZE * size);
  1055. }
  1056. }
  1057. }
  1058. break;
  1059.  
  1060. case QID_DB_STRING:
  1061. {
  1062. m_map_dbstring.clear();
  1063. m_vec_GreetMessage.clear();
  1064.  
  1065. for (uint i = 0; i < pMsg->Get()->uiNumRows; ++i)
  1066. {
  1067. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  1068. //ch->SetSafeboxSize(SAFEBOX_PAGE_SIZE * atoi(row[0]));
  1069. if (row[0] && row[1])
  1070. {
  1071. m_map_dbstring.insert(make_pair(std::string(row[0]), std::string(row[1])));
  1072. sys_log(0, "DBSTR '%s' '%s'", row[0], row[1]);
  1073. }
  1074. }
  1075. if (m_map_dbstring.find("GREET") != m_map_dbstring.end())
  1076. {
  1077. std::istringstream is(m_map_dbstring["GREET"]);
  1078. while (!is.eof())
  1079. {
  1080. std::string str;
  1081. getline(is, str);
  1082. m_vec_GreetMessage.push_back(str);
  1083. }
  1084. }
  1085. }
  1086. break;
  1087.  
  1088. case QID_LOTTO:
  1089. {
  1090. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(qi->dwIdent);
  1091. DWORD * pdw = (DWORD *) qi->pvData;
  1092.  
  1093. if (ch)
  1094. {
  1095. if (pMsg->Get()->uiAffectedRows == 0 || pMsg->Get()->uiAffectedRows == (uint32_t)-1)
  1096. {
  1097. sys_log(0, "GIVE LOTTO FAIL TO pid %u", ch->GetPlayerID());
  1098. }
  1099. else
  1100. {
  1101. LPITEM pkItem = ch->AutoGiveItem(pdw[0], pdw[1]);
  1102.  
  1103. if (pkItem)
  1104. {
  1105. sys_log(0, "GIVE LOTTO SUCCESS TO %s (pid %u)", ch->GetName(), qi->dwIdent);
  1106.  
  1107. pkItem->SetSocket(0, pMsg->Get()->uiInsertID);
  1108. pkItem->SetSocket(1, pdw[2]);
  1109. }
  1110. else
  1111. sys_log(0, "GIVE LOTTO FAIL2 TO pid %u", ch->GetPlayerID());
  1112. }
  1113. }
  1114.  
  1115. M2_DELETE_ARRAY(pdw);
  1116. }
  1117. break;
  1118.  
  1119. case QID_HIGHSCORE_REGISTER:
  1120. {
  1121. THighscoreRegisterQueryInfo * info = (THighscoreRegisterQueryInfo *) qi->pvData;
  1122. bool bQuery = true;
  1123.  
  1124. if (pMsg->Get()->uiNumRows)
  1125. {
  1126. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  1127.  
  1128. if (row && row[0])
  1129. {
  1130. int iCur = 0;
  1131. str_to_number(iCur, row[0]);
  1132.  
  1133. if ((info->bOrder && iCur >= info->iValue) ||
  1134. (!info->bOrder && iCur <= info->iValue))
  1135. bQuery = false;
  1136. }
  1137. }
  1138.  
  1139. if (bQuery)
  1140. Query("REPLACE INTO highscore%s VALUES('%s', %u, %d)",
  1141. get_table_postfix(), info->szBoard, info->dwPID, info->iValue);
  1142.  
  1143. M2_DELETE(info);
  1144. }
  1145. break;
  1146.  
  1147. case QID_HIGHSCORE_SHOW:
  1148. {
  1149. }
  1150. break;
  1151.  
  1152. // BLOCK_CHAT
  1153. case QID_BLOCK_CHAT_LIST:
  1154. {
  1155. LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(qi->dwIdent);
  1156.  
  1157. if (ch == NULL)
  1158. break;
  1159. if (pMsg->Get()->uiNumRows)
  1160. {
  1161. MYSQL_ROW row;
  1162. while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  1163. {
  1164. ch->ChatPacket(CHAT_TYPE_INFO, "%s %s sec", row[0], row[1]);
  1165. }
  1166. }
  1167. else
  1168. {
  1169. ch->ChatPacket(CHAT_TYPE_INFO, "No one currently blocked.");
  1170. }
  1171. }
  1172. break;
  1173. // END_OF_BLOCK_CHAT
  1174.  
  1175. // PCBANG_IP_LIST
  1176. case QID_PCBANG_IP_LIST_CHECK:
  1177. {
  1178. const std::string PCBANG_IP_TABLE_NAME("pcbang_ip");
  1179.  
  1180. if (pMsg->Get()->uiNumRows > 0)
  1181. {
  1182. MYSQL_ROW row;
  1183. bool isFinded = false;
  1184.  
  1185. while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  1186. {
  1187. const char* c_szName = row[0];
  1188. const char* c_szUpdateTime = row[12];
  1189.  
  1190. if (test_server)
  1191. sys_log(0, "%s:%s", c_szName, c_szUpdateTime);
  1192.  
  1193. if (PCBANG_IP_TABLE_NAME == c_szName)
  1194. {
  1195. isFinded = true;
  1196.  
  1197. static std::string s_stLastTime;
  1198. if (s_stLastTime != c_szUpdateTime)
  1199. {
  1200. s_stLastTime = c_szUpdateTime;
  1201. sys_log(0, "'%s' mysql table is UPDATED(%s)", PCBANG_IP_TABLE_NAME.c_str(), c_szUpdateTime);
  1202. ReturnQuery(QID_PCBANG_IP_LIST_SELECT, 0, NULL, "SELECT pcbang_id, ip FROM %s;", PCBANG_IP_TABLE_NAME.c_str());
  1203. }
  1204. else
  1205. {
  1206. sys_log(0, "'%s' mysql table is NOT updated(%s)", PCBANG_IP_TABLE_NAME.c_str(), c_szUpdateTime);
  1207. }
  1208. break;
  1209. }
  1210. }
  1211.  
  1212. if (!isFinded)
  1213. {
  1214. sys_err(0, "'%s' mysql table CANNOT FIND", PCBANG_IP_TABLE_NAME.c_str());
  1215. }
  1216. }
  1217. else if (test_server)
  1218. {
  1219. sys_err(0, "'%s' mysql table is NOT EXIST", PCBANG_IP_TABLE_NAME.c_str());
  1220. }
  1221. }
  1222. break;
  1223.  
  1224. case QID_PCBANG_IP_LIST_SELECT:
  1225. {
  1226. if (pMsg->Get()->uiNumRows > 0)
  1227. {
  1228. MYSQL_ROW row;
  1229.  
  1230. while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  1231. {
  1232. CPCBangManager::instance().InsertIP(row[0], row[1]);
  1233. }
  1234. }
  1235. else if (test_server)
  1236. {
  1237. sys_log(0, "PCBANG_IP_LIST is EMPTY");
  1238. }
  1239. }
  1240. break;
  1241.  
  1242.  
  1243. // END_OF_PCBANG_IP_LIST
  1244.  
  1245. case QID_BRAZIL_CREATE_ID :
  1246. {
  1247. TPacketCGLogin3 * pinfo = (TPacketCGLogin3 *) qi->pvData ;
  1248.  
  1249. if( pMsg->Get()->uiAffectedRows == 0 || pMsg->Get()->uiAffectedRows == (uint32_t)-1 )
  1250. {
  1251. LPDESC d = DESC_MANAGER::instance().FindByLoginKey(qi->dwIdent) ;
  1252. sys_log(0, "[AUTH_BRAZIL] NOID") ;
  1253. sys_log(0, "[AUTH_BRAZIL] : Failed to create a new account %s", pinfo->login) ;
  1254. LoginFailure(d, "NOID") ;
  1255. M2_DELETE(pinfo);
  1256. }
  1257. else
  1258. {
  1259. sys_log(0, "[AUTH_BRAZIL] : Succeed to create a new account %s", pinfo->login) ;
  1260.  
  1261. #ifdef __WIN32__
  1262. ReturnQuery(QID_AUTH_LOGIN, qi->dwIdent, pinfo,
  1263. "SELECT PASSWORD('%s'),password,securitycode,social_id,id,status,availDt - NOW() > 0,"
  1264. "UNIX_TIMESTAMP(silver_expire),"
  1265. "UNIX_TIMESTAMP(gold_expire),"
  1266. "UNIX_TIMESTAMP(safebox_expire),"
  1267. "UNIX_TIMESTAMP(autoloot_expire),"
  1268. "UNIX_TIMESTAMP(fish_mind_expire),"
  1269. "UNIX_TIMESTAMP(marriage_fast_expire),"
  1270. "UNIX_TIMESTAMP(money_drop_rate_expire),"
  1271. "UNIX_TIMESTAMP(create_time)"
  1272. " FROM account WHERE login='%s'", pinfo->passwd, pinfo->login);
  1273. #else
  1274. // @fixme138 1. PASSWORD('%s') -> %s 2. pinfo->passwd wrapped inside Argon2PasswordHash(%s).c_str()
  1275. ReturnQuery(QID_AUTH_LOGIN, qi->dwIdent, pinfo,
  1276. "SELECT '%s',password,securitycode,social_id,id,status,availDt - NOW() > 0,"
  1277. "UNIX_TIMESTAMP(silver_expire),"
  1278. "UNIX_TIMESTAMP(gold_expire),"
  1279. "UNIX_TIMESTAMP(safebox_expire),"
  1280. "UNIX_TIMESTAMP(autoloot_expire),"
  1281. "UNIX_TIMESTAMP(fish_mind_expire),"
  1282. "UNIX_TIMESTAMP(marriage_fast_expire),"
  1283. "UNIX_TIMESTAMP(money_drop_rate_expire),"
  1284. "UNIX_TIMESTAMP(create_time)"
  1285. " FROM account WHERE login='%s'",
  1286. Argon2PasswordHash(pinfo->passwd).c_str(), pinfo->login) ;
  1287. #endif
  1288. }
  1289. }
  1290. break;
  1291.  
  1292. default:
  1293. sys_err("FATAL ERROR!!! Unhandled return query id %d", qi->iType);
  1294. break;
  1295. }
  1296.  
  1297. M2_DELETE(qi);
  1298. }
  1299.  
  1300. void DBManager::LoadDBString()
  1301. {
  1302. ReturnQuery(QID_DB_STRING, 0, NULL, "SELECT name, text FROM string%s", get_table_postfix());
  1303. }
  1304.  
  1305. const std::string& DBManager::GetDBString(const std::string& key)
  1306. {
  1307. static std::string null_str = "";
  1308. itertype(m_map_dbstring) it = m_map_dbstring.find(key);
  1309. if (it == m_map_dbstring.end())
  1310. return null_str;
  1311. return it->second;
  1312. }
  1313.  
  1314. const std::vector<std::string>& DBManager::GetGreetMessage()
  1315. {
  1316. return m_vec_GreetMessage;
  1317. }
  1318.  
  1319. void DBManager::SendMoneyLog(BYTE type, DWORD vnum, int gold)
  1320. {
  1321. if (!gold)
  1322. return;
  1323. TPacketMoneyLog p;
  1324. p.type = type;
  1325. p.vnum = vnum;
  1326. p.gold = gold;
  1327. db_clientdesc->DBPacket(HEADER_GD_MONEY_LOG, 0, &p, sizeof(p));
  1328. }
  1329.  
  1330. void VCardUse(LPCHARACTER CardOwner, LPCHARACTER CardTaker, LPITEM item)
  1331. {
  1332. TPacketGDVCard p;
  1333.  
  1334. p.dwID = item->GetSocket(0);
  1335. strlcpy(p.szSellCharacter, CardOwner->GetName(), sizeof(p.szSellCharacter));
  1336. strlcpy(p.szSellAccount, CardOwner->GetDesc()->GetAccountTable().login, sizeof(p.szSellAccount));
  1337. strlcpy(p.szBuyCharacter, CardTaker->GetName(), sizeof(p.szBuyCharacter));
  1338. strlcpy(p.szBuyAccount, CardTaker->GetDesc()->GetAccountTable().login, sizeof(p.szBuyAccount));
  1339.  
  1340. db_clientdesc->DBPacket(HEADER_GD_VCARD, 0, &p, sizeof(TPacketGDVCard));
  1341.  
  1342. CardTaker->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d분의 결제시간이 추가 되었습니다. (결제번호 %d)"), item->GetSocket(1) / 60, item->GetSocket(0));
  1343.  
  1344. LogManager::instance().VCardLog(p.dwID, CardTaker->GetX(), CardTaker->GetY(), g_stHostname.c_str(),
  1345. CardOwner->GetName(), CardOwner->GetDesc()->GetHostName(),
  1346. CardTaker->GetName(), CardTaker->GetDesc()->GetHostName());
  1347.  
  1348. ITEM_MANAGER::instance().RemoveItem(item);
  1349.  
  1350. sys_log(0, "VCARD_TAKE: %u %s -> %s", p.dwID, CardOwner->GetName(), CardTaker->GetName());
  1351. }
  1352.  
  1353. void DBManager::StopAllBilling()
  1354. {
  1355. for (itertype(m_map_pkLoginData) it = m_map_pkLoginData.begin(); it != m_map_pkLoginData.end(); ++it)
  1356. {
  1357. SetBilling(it->first, false);
  1358. }
  1359. }
  1360.  
  1361. void DBManager::RequestBlockException(const char *login, int cmd)
  1362. {
  1363. TPacketBlockException packet;
  1364.  
  1365. packet.cmd = cmd;
  1366. strlcpy(packet.login, login, sizeof(packet.login));
  1367. db_clientdesc->DBPacket(HEADER_GD_BLOCK_EXCEPTION, 0, &packet, sizeof(packet));
  1368. }
  1369.  
  1370. size_t DBManager::EscapeString(char* dst, size_t dstSize, const char *src, size_t srcSize)
  1371. {
  1372. return m_sql_direct.EscapeString(dst, dstSize, src, srcSize);
  1373. }
  1374.  
  1375. //
  1376. // Common SQL
  1377. //
  1378. AccountDB::AccountDB() : m_IsConnect(false) {
  1379. // Constructor implementation
  1380. // Initialize member variables, perform any setup
  1381. }
  1382.  
  1383. std::string DBManager::Argon2PasswordHash(const char* c_pszPassword, const char* salt)
  1384. {
  1385. std::string returnStr = "";
  1386.  
  1387. uint8_t hash[EArgon2::HASH_LENGHT];
  1388. uint32_t saltlen = strlen(salt);
  1389.  
  1390. uint8_t* pwd = (uint8_t*)strdup(c_pszPassword);
  1391. uint32_t pwdlen = strlen((char*)pwd);
  1392.  
  1393. argon2id_hash_raw(EArgon2::TIME_COST, EArgon2::MEMORY_COST, EArgon2::PARALLELISM, pwd, pwdlen, (uint8_t*)salt, saltlen, hash, EArgon2::HASH_LENGHT);
  1394. free(pwd);
  1395.  
  1396. char s_buffer[EArgon2::HASH_LENGHT * 2 + 1];
  1397. memset(s_buffer, 0x00, sizeof(s_buffer));
  1398. for (uint32_t i = 0; i < EArgon2::HASH_LENGHT; ++i) {
  1399. sprintf(s_buffer + (i * 2), "%02x", hash[i]);
  1400. }
  1401.  
  1402. returnStr = s_buffer;
  1403. return returnStr;
  1404. }
  1405.  
  1406.  
  1407. bool AccountDB::IsConnected()
  1408. {
  1409. return m_IsConnect;
  1410. }
  1411.  
  1412. bool AccountDB::Connect(const char * host, const int port, const char * user, const char * pwd, const char * db)
  1413. {
  1414. m_IsConnect = m_sql_direct.Setup(host, user, pwd, db, "", true, port);
  1415.  
  1416. if (false == m_IsConnect)
  1417. {
  1418. fprintf(stderr, "cannot open direct sql connection to host: %s user: %s db: %s\n", host, user, db);
  1419. return false;
  1420. }
  1421.  
  1422. return m_IsConnect;
  1423. }
  1424.  
  1425. bool AccountDB::ConnectAsync(const char * host, const int port, const char * user, const char * pwd, const char * db, const char * locale)
  1426. {
  1427. m_sql.Setup(host, user, pwd, db, locale, false, port);
  1428. return true;
  1429. }
  1430.  
  1431. void AccountDB::SetLocale(const std::string & stLocale)
  1432. {
  1433. m_sql_direct.SetLocale(stLocale);
  1434. m_sql_direct.QueryLocaleSet();
  1435. }
  1436.  
  1437. SQLMsg* AccountDB::DirectQuery(const char * query)
  1438. {
  1439. return m_sql_direct.DirectQuery(query);
  1440. }
  1441.  
  1442. void AccountDB::AsyncQuery(const char* query)
  1443. {
  1444. m_sql.AsyncQuery(query);
  1445. }
  1446.  
  1447. void AccountDB::ReturnQuery(int iType, DWORD dwIdent, void * pvData, const char * c_pszFormat, ...)
  1448. {
  1449. char szQuery[4096];
  1450. va_list args;
  1451.  
  1452. va_start(args, c_pszFormat);
  1453. vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
  1454. va_end(args);
  1455.  
  1456. CReturnQueryInfo * p = M2_NEW CReturnQueryInfo;
  1457.  
  1458. p->iQueryType = QUERY_TYPE_RETURN;
  1459. p->iType = iType;
  1460. p->dwIdent = dwIdent;
  1461. p->pvData = pvData;
  1462.  
  1463. m_sql.ReturnQuery(szQuery, p);
  1464. }
  1465.  
  1466. SQLMsg * AccountDB::PopResult()
  1467. {
  1468. SQLMsg * p;
  1469.  
  1470. if (m_sql.PopResult(&p))
  1471. return p;
  1472.  
  1473. return NULL;
  1474. }
  1475.  
  1476. void AccountDB::Process()
  1477. {
  1478. SQLMsg* pMsg = NULL;
  1479.  
  1480. while ((pMsg = PopResult()))
  1481. {
  1482. CQueryInfo* qi = (CQueryInfo *) pMsg->pvUserData;
  1483.  
  1484. switch (qi->iQueryType)
  1485. {
  1486. case QUERY_TYPE_RETURN:
  1487. AnalyzeReturnQuery(pMsg);
  1488. break;
  1489. }
  1490. }
  1491.  
  1492. delete pMsg;
  1493. }
  1494.  
  1495. extern unsigned int g_uiSpamReloadCycle;
  1496.  
  1497. enum EAccountQID
  1498. {
  1499. QID_SPAM_DB,
  1500. };
  1501.  
  1502.  
  1503. static LPEVENT s_pkReloadSpamEvent = NULL;
  1504.  
  1505. EVENTINFO(reload_spam_event_info)
  1506. {
  1507. // used to send command
  1508. DWORD empty;
  1509. };
  1510.  
  1511. EVENTFUNC(reload_spam_event)
  1512. {
  1513. AccountDB::instance().ReturnQuery(QID_SPAM_DB, 0, NULL, "SELECT word, score FROM spam_db WHERE type='SPAM'");
  1514. return PASSES_PER_SEC(g_uiSpamReloadCycle);
  1515. }
  1516.  
  1517. // #define ENABLE_SPAMDB_REFRESH
  1518. void LoadSpamDB()
  1519. {
  1520. AccountDB::instance().ReturnQuery(QID_SPAM_DB, 0, NULL, "SELECT word, score FROM spam_db WHERE type='SPAM'");
  1521. #ifdef ENABLE_SPAMDB_REFRESH
  1522. if (NULL == s_pkReloadSpamEvent)
  1523. {
  1524. reload_spam_event_info* info = AllocEventInfo<reload_spam_event_info>();
  1525. s_pkReloadSpamEvent = event_create(reload_spam_event, info, PASSES_PER_SEC(g_uiSpamReloadCycle));
  1526. }
  1527. #endif
  1528. }
  1529.  
  1530. void CancelReloadSpamEvent() {
  1531. s_pkReloadSpamEvent = NULL;
  1532. }
  1533.  
  1534. void AccountDB::AnalyzeReturnQuery(SQLMsg * pMsg)
  1535. {
  1536. CReturnQueryInfo * qi = (CReturnQueryInfo *) pMsg->pvUserData;
  1537.  
  1538. switch (qi->iType)
  1539. {
  1540. case QID_SPAM_DB:
  1541. {
  1542. if (pMsg->Get()->uiNumRows > 0)
  1543. {
  1544. MYSQL_ROW row;
  1545.  
  1546. SpamManager::instance().Clear();
  1547.  
  1548. while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  1549. SpamManager::instance().Insert(row[0], atoi(row[1]));
  1550. }
  1551. }
  1552. break;
  1553. }
  1554.  
  1555. M2_DELETE(qi);
  1556. }
  1557.  
  1558.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement