Advertisement
Guest User

Untitled

a guest
Nov 13th, 2023
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.41 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.  
  25.  
  26. bool CheckPasspod(const char * account)
  27. {
  28. char szQuery[1024];
  29.  
  30. snprintf(szQuery, sizeof(szQuery), "SELECT ID FROM passpod WHERE Login='%s'", account);
  31. SQLMsg * pMsg = DBManager::instance().DirectQuery(szQuery);
  32.  
  33. if (!pMsg)
  34. {
  35. //fprintf(stderr, "cannot get the MATRIX\n");
  36. sys_log(0, "cannot get the PASSPOD");
  37. delete pMsg;
  38. return false;
  39. }
  40.  
  41. if (pMsg->Get()->uiNumRows == 0)
  42. {
  43. puts(szQuery);
  44. sys_log(0, "[PASSPOD]DirectQuery failed(%s)", szQuery);
  45.  
  46. delete pMsg;
  47. return false;
  48. }
  49.  
  50. delete pMsg;
  51.  
  52. return true;
  53. }
  54.  
  55.  
  56. DBManager::DBManager() : m_bIsConnect(false)
  57. {
  58. }
  59.  
  60. DBManager::~DBManager()
  61. {
  62. }
  63.  
  64. bool DBManager::Connect(const char * host, const int port, const char * user, const char * pwd, const char * db)
  65. {
  66. if (m_sql.Setup(host, user, pwd, db, g_stLocale.c_str(), false, port))
  67. m_bIsConnect = true;
  68.  
  69. if (!m_sql_direct.Setup(host, user, pwd, db, g_stLocale.c_str(), true, port))
  70. sys_err("cannot open direct sql connection to host %s", host);
  71.  
  72. if (m_bIsConnect && !g_bAuthServer)
  73. {
  74. LoadDBString();
  75. }
  76.  
  77. return m_bIsConnect;
  78. }
  79.  
  80. void DBManager::Query(const char * c_pszFormat, ...)
  81. {
  82. char szQuery[4096];
  83. va_list args;
  84.  
  85. va_start(args, c_pszFormat);
  86. vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
  87. va_end(args);
  88.  
  89. m_sql.AsyncQuery(szQuery);
  90. }
  91.  
  92. SQLMsg * DBManager::DirectQuery(const char * c_pszFormat, ...)
  93. {
  94. char szQuery[4096];
  95. va_list args;
  96.  
  97. va_start(args, c_pszFormat);
  98. vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
  99. va_end(args);
  100.  
  101. return m_sql_direct.DirectQuery(szQuery);
  102. }
  103.  
  104. bool DBManager::IsConnected()
  105. {
  106. return m_bIsConnect;
  107. }
  108.  
  109. void DBManager::ReturnQuery(int iType, DWORD dwIdent, void * pvData, const char * c_pszFormat, ...)
  110. {
  111. //sys_log(0, "ReturnQuery %s", c_pszQuery);
  112. char szQuery[4096];
  113. va_list args;
  114.  
  115. va_start(args, c_pszFormat);
  116. vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
  117. va_end(args);
  118.  
  119. CReturnQueryInfo * p = M2_NEW CReturnQueryInfo;
  120.  
  121. p->iQueryType = QUERY_TYPE_RETURN;
  122. p->iType = iType;
  123. p->dwIdent = dwIdent;
  124. p->pvData = pvData;
  125.  
  126. m_sql.ReturnQuery(szQuery, p);
  127. }
  128.  
  129. SQLMsg * DBManager::PopResult()
  130. {
  131. SQLMsg * p;
  132.  
  133. if (m_sql.PopResult(&p))
  134. return p;
  135.  
  136. return NULL;
  137. }
  138.  
  139. void DBManager::Process()
  140. {
  141. SQLMsg* pMsg = NULL;
  142.  
  143. while ((pMsg = PopResult()))
  144. {
  145. if( NULL != pMsg->pvUserData )
  146. {
  147. switch( reinterpret_cast<CQueryInfo*>(pMsg->pvUserData)->iQueryType )
  148. {
  149. case QUERY_TYPE_RETURN:
  150. AnalyzeReturnQuery(pMsg);
  151. break;
  152.  
  153. case QUERY_TYPE_FUNCTION:
  154. {
  155. CFuncQueryInfo* qi = reinterpret_cast<CFuncQueryInfo*>( pMsg->pvUserData );
  156. qi->f(pMsg);
  157. M2_DELETE(qi);
  158. }
  159. break;
  160.  
  161. case QUERY_TYPE_AFTER_FUNCTION:
  162. {
  163. CFuncAfterQueryInfo* qi = reinterpret_cast<CFuncAfterQueryInfo*>( pMsg->pvUserData );
  164. qi->f();
  165. M2_DELETE(qi);
  166. }
  167. break;
  168. }
  169. }
  170.  
  171. delete pMsg;
  172. }
  173. }
  174.  
  175. CLoginData * DBManager::GetLoginData(DWORD dwKey)
  176. {
  177. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(dwKey);
  178.  
  179. if (it == m_map_pkLoginData.end())
  180. return NULL;
  181.  
  182. return it->second;
  183. }
  184.  
  185. void DBManager::InsertLoginData(CLoginData * pkLD)
  186. {
  187. m_map_pkLoginData.insert(std::make_pair(pkLD->GetKey(), pkLD));
  188. }
  189.  
  190. void DBManager::DeleteLoginData(CLoginData * pkLD)
  191. {
  192. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(pkLD->GetKey());
  193.  
  194. if (it == m_map_pkLoginData.end())
  195. return;
  196.  
  197. sys_log(0, "DeleteLoginData %s %p", pkLD->GetLogin(), pkLD);
  198.  
  199. mapLDBilling.erase(pkLD->GetLogin());
  200.  
  201. M2_DELETE(it->second);
  202. m_map_pkLoginData.erase(it);
  203. }
  204.  
  205. void DBManager::SetBilling(DWORD dwKey, bool bOn, bool bSkipPush)
  206. {
  207. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(dwKey);
  208.  
  209. if (it == m_map_pkLoginData.end())
  210. {
  211. sys_err("cannot find login key %u", dwKey);
  212. return;
  213. }
  214.  
  215. CLoginData * ld = it->second;
  216.  
  217. itertype(mapLDBilling) it2 = mapLDBilling.find(ld->GetLogin());
  218.  
  219. if (it2 != mapLDBilling.end())
  220. if (it2->second != ld)
  221. DeleteLoginData(it2->second);
  222.  
  223. mapLDBilling.insert(std::make_pair(ld->GetLogin(), ld));
  224.  
  225. if (ld->IsBilling() && !bOn && !bSkipPush)
  226. PushBilling(ld);
  227.  
  228. SendLoginPing(ld->GetLogin());
  229. ld->SetBilling(bOn);
  230. }
  231.  
  232. void DBManager::PushBilling(CLoginData * pkLD)
  233. {
  234. TUseTime t;
  235.  
  236. t.dwUseSec = (get_dword_time() - pkLD->GetLogonTime()) / 1000;
  237.  
  238. if (t.dwUseSec <= 0)
  239. return;
  240.  
  241. pkLD->SetLogonTime();
  242. long lRemainSecs = pkLD->GetRemainSecs() - t.dwUseSec;
  243. pkLD->SetRemainSecs(MAX(0, lRemainSecs));
  244.  
  245. t.dwLoginKey = pkLD->GetKey();
  246. t.bBillType = pkLD->GetBillType();
  247.  
  248. sys_log(0, "BILLING: PUSH %s %u type %u", pkLD->GetLogin(), t.dwUseSec, t.bBillType);
  249.  
  250. if (t.bBillType == BILLING_IP_FREE || t.bBillType == BILLING_IP_TIME || t.bBillType == BILLING_IP_DAY)
  251. snprintf(t.szLogin, sizeof(t.szLogin), "%u", pkLD->GetBillID());
  252. else
  253. strlcpy(t.szLogin, pkLD->GetLogin(), sizeof(t.szLogin));
  254.  
  255. strlcpy(t.szIP, pkLD->GetIP(), sizeof(t.szIP));
  256.  
  257. m_vec_kUseTime.push_back(t);
  258. }
  259.  
  260. void DBManager::FlushBilling(bool bForce)
  261. {
  262. if (bForce)
  263. {
  264. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.begin();
  265.  
  266. while (it != m_map_pkLoginData.end())
  267. {
  268. CLoginData * pkLD = (it++)->second;
  269.  
  270. if (pkLD->IsBilling())
  271. PushBilling(pkLD);
  272. }
  273. }
  274.  
  275. if (!m_vec_kUseTime.empty())
  276. {
  277. DWORD dwCount = 0;
  278.  
  279. std::vector<TUseTime>::iterator it = m_vec_kUseTime.begin();
  280.  
  281. while (it != m_vec_kUseTime.end())
  282. {
  283. TUseTime * p = &(*(it++));
  284.  
  285. // DISABLE_OLD_BILLING_CODE
  286. if (!g_bBilling)
  287. {
  288. ++dwCount;
  289. continue;
  290. }
  291.  
  292. Query("INSERT GameTimeLog (login, type, logon_time, logout_time, use_time, ip, server) "
  293. "VALUES('%s', %u, DATE_SUB(NOW(), INTERVAL %u SECOND), NOW(), %u, '%s', '%s')",
  294. p->szLogin, p->bBillType, p->dwUseSec, p->dwUseSec, p->szIP, g_stHostname.c_str());
  295. // DISABLE_OLD_BILLING_CODE_END
  296.  
  297. switch (p->bBillType)
  298. {
  299. case BILLING_FREE:
  300. case BILLING_IP_FREE:
  301. break;
  302.  
  303. case BILLING_DAY:
  304. {
  305. if (!bForce)
  306. {
  307. TUseTime * pInfo = M2_NEW TUseTime;
  308. memcpy(pInfo, p, sizeof(TUseTime));
  309. ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
  310. "SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTime WHERE UserID='%s'", p->szLogin);
  311. }
  312. }
  313. break;
  314.  
  315. case BILLING_TIME:
  316. {
  317. Query("UPDATE GameTime SET LimitTime=LimitTime-%u WHERE UserID='%s'", p->dwUseSec, p->szLogin);
  318.  
  319. if (!bForce)
  320. {
  321. TUseTime * pInfo = M2_NEW TUseTime;
  322. memcpy(pInfo, p, sizeof(TUseTime));
  323. ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
  324. "SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTime WHERE UserID='%s'", p->szLogin);
  325. }
  326. }
  327. break;
  328.  
  329. case BILLING_IP_DAY:
  330. {
  331. if (!bForce)
  332. {
  333. TUseTime * pInfo = M2_NEW TUseTime;
  334. memcpy(pInfo, p, sizeof(TUseTime));
  335. ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
  336. "SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTimeIP WHERE ipid=%s", p->szLogin);
  337. }
  338. }
  339. break;
  340.  
  341. case BILLING_IP_TIME:
  342. {
  343. Query("UPDATE GameTimeIP SET LimitTime=LimitTime-%u WHERE ipid=%s", p->dwUseSec, p->szLogin);
  344.  
  345. if (!bForce)
  346. {
  347. TUseTime * pInfo = M2_NEW TUseTime;
  348. memcpy(pInfo, p, sizeof(TUseTime));
  349. ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
  350. "SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTimeIP WHERE ipid=%s", p->szLogin);
  351. }
  352. }
  353. break;
  354. }
  355.  
  356. if (!bForce && ++dwCount >= 1000)
  357. break;
  358. }
  359.  
  360. if (dwCount < m_vec_kUseTime.size())
  361. {
  362. int nNewSize = m_vec_kUseTime.size() - dwCount;
  363. memcpy(&m_vec_kUseTime[0], &m_vec_kUseTime[dwCount], sizeof(TUseTime) * nNewSize);
  364. m_vec_kUseTime.resize(nNewSize);
  365. }
  366. else
  367. m_vec_kUseTime.clear();
  368.  
  369. sys_log(0, "FLUSH_USE_TIME: count %u", dwCount);
  370. }
  371.  
  372. if (m_vec_kUseTime.size() < 10240)
  373. {
  374. DWORD dwCurTime = get_dword_time();
  375.  
  376. std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.begin();
  377.  
  378. while (it != m_map_pkLoginData.end())
  379. {
  380. CLoginData * pkLD = (it++)->second;
  381.  
  382. if (!pkLD->IsBilling())
  383. continue;
  384.  
  385. switch (pkLD->GetBillType())
  386. {
  387. case BILLING_IP_FREE:
  388. case BILLING_FREE:
  389. break;
  390.  
  391. case BILLING_IP_DAY:
  392. case BILLING_DAY:
  393. case BILLING_IP_TIME:
  394. case BILLING_TIME:
  395. if (pkLD->GetRemainSecs() < 0)
  396. {
  397. DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
  398.  
  399. if (dwSecsConnected % 10 == 0)
  400. SendBillingExpire(pkLD->GetLogin(), BILLING_DAY, 0, pkLD);
  401. }
  402. else if (pkLD->GetRemainSecs() <= 600) // if remain seconds lower than 10 minutes
  403. {
  404. DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
  405.  
  406. if (dwSecsConnected >= 60) // 60 second cycle
  407. {
  408. sys_log(0, "BILLING 1 %s remain %d connected secs %u",
  409. pkLD->GetLogin(), pkLD->GetRemainSecs(), dwSecsConnected);
  410. PushBilling(pkLD);
  411. }
  412. }
  413. else
  414. {
  415. DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
  416.  
  417. if (dwSecsConnected > (DWORD) (pkLD->GetRemainSecs() - 600) || dwSecsConnected >= 600)
  418. {
  419. sys_log(0, "BILLING 2 %s remain %d connected secs %u",
  420. pkLD->GetLogin(), pkLD->GetRemainSecs(), dwSecsConnected);
  421. PushBilling(pkLD);
  422. }
  423. }
  424. break;
  425. }
  426. }
  427. }
  428.  
  429. }
  430.  
  431. void DBManager::CheckBilling()
  432. {
  433. std::vector<DWORD> vec;
  434. vec.push_back(0);
  435.  
  436. //sys_log(0, "CheckBilling: map size %d", m_map_pkLoginData.size());
  437.  
  438. itertype(m_map_pkLoginData) it = m_map_pkLoginData.begin();
  439.  
  440. while (it != m_map_pkLoginData.end())
  441. {
  442. CLoginData * pkLD = (it++)->second;
  443.  
  444. if (pkLD->IsBilling())
  445. {
  446. sys_log(0, "BILLING: CHECK %u", pkLD->GetKey());
  447. vec.push_back(pkLD->GetKey());
  448. }
  449. }
  450.  
  451. vec[0] = vec.size() - 1;
  452. db_clientdesc->DBPacket(HEADER_GD_BILLING_CHECK, 0, &vec[0], sizeof(DWORD) * vec.size());
  453. }
  454.  
  455. void DBManager::SendLoginPing(const char * c_pszLogin)
  456. {
  457. TPacketGGLoginPing ptog;
  458.  
  459. ptog.bHeader = HEADER_GG_LOGIN_PING;
  460. strlcpy(ptog.szLogin, c_pszLogin, sizeof(ptog.szLogin));
  461.  
  462. if (!g_pkAuthMasterDesc) // If I am master, broadcast to others
  463. {
  464. P2P_MANAGER::instance().Send(&ptog, sizeof(TPacketGGLoginPing));
  465. }
  466. else // If I am slave send login ping to master
  467. {
  468. g_pkAuthMasterDesc->Packet(&ptog, sizeof(TPacketGGLoginPing));
  469. }
  470. }
  471.  
  472. void DBManager::SendAuthLogin(LPDESC d)
  473. {
  474. const TAccountTable & r = d->GetAccountTable();
  475.  
  476. CLoginData * pkLD = GetLoginData(d->GetLoginKey());
  477.  
  478. if (!pkLD)
  479. return;
  480.  
  481. TPacketGDAuthLogin ptod;
  482. ptod.dwID = r.id;
  483.  
  484. trim_and_lower(r.login, ptod.szLogin, sizeof(ptod.szLogin));
  485. strlcpy(ptod.szSocialID, r.social_id, sizeof(ptod.szSocialID));
  486. ptod.dwLoginKey = d->GetLoginKey();
  487. ptod.bBillType = pkLD->GetBillType();
  488. ptod.dwBillID = pkLD->GetBillID();
  489. #ifdef __MULTI_LANGUAGE_SYSTEM__
  490. ptod.bLanguage = r.bLanguage;
  491. #endif
  492. thecore_memcpy(ptod.iPremiumTimes, pkLD->GetPremiumPtr(), sizeof(ptod.iPremiumTimes));
  493. thecore_memcpy(&ptod.adwClientKey, pkLD->GetClientKey(), sizeof(DWORD) * 4);
  494.  
  495. db_clientdesc->DBPacket(HEADER_GD_AUTH_LOGIN, d->GetHandle(), &ptod, sizeof(TPacketGDAuthLogin));
  496. #ifdef __MULTI_LANGUAGE_SYSTEM__
  497. sys_log(0, "SendAuthLogin %s language %d key %u", ptod.szLogin, ptod.bLanguage, ptod.dwID);
  498. #else
  499. sys_log(0, "SendAuthLogin %s key %u", ptod.szLogin, ptod.dwID);
  500. #endif
  501.  
  502. SendLoginPing(r.login);
  503. }
  504.  
  505. void DBManager::LoginPrepare(BYTE bBillType, DWORD dwBillID, long lRemainSecs, LPDESC d, DWORD * pdwClientKey, int * paiPremiumTimes)
  506. {
  507. const TAccountTable & r = d->GetAccountTable();
  508.  
  509. CLoginData * pkLD = M2_NEW CLoginData;
  510.  
  511. pkLD->SetKey(d->GetLoginKey());
  512. pkLD->SetLogin(r.login);
  513. pkLD->SetBillType(bBillType);
  514. pkLD->SetBillID(dwBillID);
  515. pkLD->SetRemainSecs(lRemainSecs);
  516. pkLD->SetIP(d->GetHostName());
  517. pkLD->SetClientKey(pdwClientKey);
  518.  
  519. if (paiPremiumTimes)
  520. pkLD->SetPremium(paiPremiumTimes);
  521.  
  522. InsertLoginData(pkLD);
  523.  
  524. if (*d->GetMatrixCode())
  525. {
  526. unsigned long rows = 0, cols = 0;
  527. MatrixCardRndCoordinate(rows, cols);
  528.  
  529. d->SetMatrixCardRowsAndColumns(rows, cols);
  530.  
  531. TPacketGCMatrixCard pm;
  532.  
  533. pm.bHeader = HEADER_GC_MATRIX_CARD;
  534. pm.dwRows = rows;
  535. pm.dwCols = cols;
  536.  
  537. d->Packet(&pm, sizeof(TPacketGCMatrixCard));
  538.  
  539. sys_log(0, "MATRIX_QUERY: %s %c%d %c%d %c%d %c%d %s",
  540. r.login,
  541. MATRIX_CARD_ROW(rows, 0) + 'A',
  542. MATRIX_CARD_COL(cols, 0) + 1,
  543. MATRIX_CARD_ROW(rows, 1) + 'A',
  544. MATRIX_CARD_COL(cols, 1) + 1,
  545. MATRIX_CARD_ROW(rows, 2) + 'A',
  546. MATRIX_CARD_COL(cols, 2) + 1,
  547. MATRIX_CARD_ROW(rows, 3) + 'A',
  548. MATRIX_CARD_COL(cols, 3) + 1,
  549. d->GetMatrixCode());
  550. }
  551. else
  552. {
  553. #ifdef ENABLE_PASSPOD_FEATURE // @warme006
  554. {
  555. if (!g_bNoPasspod)
  556. {
  557. if (CheckPasspod(r.login))
  558. {
  559. BYTE id = HEADER_GC_REQUEST_PASSPOD;
  560. d->Packet(&id, sizeof(BYTE));
  561. sys_log(0, "%s request passpod", r.login);
  562. }
  563. else
  564. {
  565. SendAuthLogin(d);
  566.  
  567. }
  568. }
  569. else
  570. {
  571. SendAuthLogin(d);
  572. }
  573. }
  574. #else
  575. SendAuthLogin(d);
  576. #endif
  577. }
  578. }
  579.  
  580. bool GetGameTimeIP(MYSQL_RES * pRes, BYTE & bBillType, DWORD & dwBillID, int & seconds, const char * c_pszIP)
  581. {
  582. if (!pRes)
  583. return true;
  584.  
  585. MYSQL_ROW row = mysql_fetch_row(pRes);
  586. int col = 0;
  587.  
  588. str_to_number(dwBillID, row[col++]);
  589.  
  590. int ip_start = 0;
  591. str_to_number(ip_start, row[col++]);
  592.  
  593. int ip_end = 0;
  594. str_to_number(ip_end, row[col++]);
  595.  
  596. int type = 0;
  597. str_to_number(type, row[col++]);
  598.  
  599. str_to_number(seconds, row[col++]);
  600.  
  601. int day_seconds = 0;
  602. str_to_number(day_seconds, row[col++]);
  603.  
  604. char szIP[MAX_HOST_LENGTH + 1];
  605. strlcpy(szIP, c_pszIP, sizeof(szIP));
  606.  
  607. char * p = strrchr(szIP, '.');
  608. ++p;
  609.  
  610. int ip_postfix = 0;
  611. str_to_number(ip_postfix, p);
  612. int valid_ip = false;
  613.  
  614. if (ip_start <= ip_postfix && ip_end >= ip_postfix)
  615. valid_ip = true;
  616.  
  617. bBillType = BILLING_NONE;
  618.  
  619. if (valid_ip)
  620. {
  621. if (type == -1)
  622. return false;
  623.  
  624. if (type == 0)
  625. bBillType = BILLING_IP_FREE;
  626. else if (day_seconds > 0)
  627. {
  628. bBillType = BILLING_IP_DAY;
  629. seconds = day_seconds;
  630. }
  631. else if (seconds > 0)
  632. bBillType = BILLING_IP_TIME;
  633. }
  634.  
  635. return true;
  636. }
  637.  
  638. bool GetGameTime(MYSQL_RES * pRes, BYTE & bBillType, int & seconds)
  639. {
  640. if (!pRes)
  641. return true;
  642.  
  643. MYSQL_ROW row = mysql_fetch_row(pRes);
  644. sys_log(1, "GetGameTime %p %p %p", row[0], row[1], row[2]);
  645.  
  646. int type = 0;
  647. str_to_number(type, row[0]);
  648. str_to_number(seconds, row[1]);
  649. int day_seconds = 0;
  650. str_to_number(day_seconds, row[2]);
  651. bBillType = BILLING_NONE;
  652.  
  653. if (type == -1)
  654. return false;
  655. else if (type == 0)
  656. bBillType = BILLING_FREE;
  657. else if (day_seconds > 0)
  658. {
  659. bBillType = BILLING_DAY;
  660. seconds = day_seconds;
  661. }
  662. else if (seconds > 0)
  663. bBillType = BILLING_TIME;
  664.  
  665. if (!g_bBilling)
  666. bBillType = BILLING_FREE;
  667.  
  668. return true;
  669. }
  670.  
  671. void SendBillingExpire(const char * c_pszLogin, BYTE bBillType, int iSecs, CLoginData * pkLD)
  672. {
  673. TPacketBillingExpire ptod;
  674.  
  675. strlcpy(ptod.szLogin, c_pszLogin, sizeof(ptod.szLogin));
  676. ptod.bBillType = bBillType;
  677. ptod.dwRemainSeconds = MAX(0, iSecs);
  678. db_clientdesc->DBPacket(HEADER_GD_BILLING_EXPIRE, 0, &ptod, sizeof(TPacketBillingExpire));
  679. sys_log(0, "BILLING: EXPIRE %s type %d sec %d ptr %p", c_pszLogin, bBillType, iSecs, pkLD);
  680. }
  681.  
  682. void DBManager::AnalyzeReturnQuery(SQLMsg * pMsg)
  683. {
  684. CReturnQueryInfo * qi = (CReturnQueryInfo *) pMsg->pvUserData;
  685.  
  686. switch (qi->iType)
  687. {
  688. case QID_AUTH_LOGIN:
  689. {
  690. TPacketCGLogin3 * pinfo = (TPacketCGLogin3 *) qi->pvData;
  691. LPDESC d = DESC_MANAGER::instance().FindByLoginKey(qi->dwIdent);
  692.  
  693. if (!d)
  694. {
  695. M2_DELETE(pinfo);
  696. break;
  697. }
  698.  
  699. d->SetLogin(pinfo->login);
  700.  
  701. sys_log(0, "QID_AUTH_LOGIN: START %u %p", qi->dwIdent, get_pointer(d));
  702.  
  703. if (pMsg->Get()->uiNumRows == 0)
  704. {
  705. #ifdef ENABLE_BRAZIL_AUTH_FEATURE // @warme006
  706. {
  707.  
  708. // @fixme138 1. PASSWORD('%s') -> %s 2. pinfo->passwd wrapped inside mysql_hash_password(%s).c_str()
  709. ReturnQuery(QID_BRAZIL_CREATE_ID, qi->dwIdent, pinfo,
  710. "INSERT INTO account(login, password, social_id, create_time) "
  711. "VALUES('%s', '%s', '0000000', NOW()) ;",
  712. pinfo->login, mysql_hash_password(pinfo->passwd).c_str());
  713.  
  714. sys_log(0, "[AUTH_BRAZIL] : Create A new AccountID From OnGame");
  715. }
  716. #else
  717. {
  718. sys_log(0, " NOID");
  719. LoginFailure(d, "NOID");
  720. M2_DELETE(pinfo);
  721. }
  722. #endif
  723. }
  724. else
  725. {
  726. MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
  727. int col = 0;
  728.  
  729. // PASSWORD('%s'), password, securitycode, social_id, id, status
  730. char szEncrytPassword[45 + 1] = {0, };
  731. char szPassword[45 + 1] = {0, };
  732. char szMatrixCode[MATRIX_CODE_MAX_LEN + 1] = {0, };
  733. char szSocialID[SOCIAL_ID_MAX_LEN + 1] = {0, };
  734. char szStatus[ACCOUNT_STATUS_MAX_LEN + 1] = {0, };
  735. DWORD dwID = 0;
  736.  
  737. #ifdef __MULTI_LANGUAGE_SYSTEM__
  738. BYTE bLanguage = LOCALE_DEFAULT;
  739. #endif
  740. if (!row[col])
  741. {
  742. sys_err("error column %d", col);
  743. M2_DELETE(pinfo);
  744. break;
  745. }
  746.  
  747. strlcpy(szEncrytPassword, row[col++], sizeof(szEncrytPassword));
  748.  
  749. if (!row[col])
  750. {
  751. sys_err("error column %d", col);
  752. M2_DELETE(pinfo);
  753. break;
  754. }
  755.  
  756. strlcpy(szPassword, row[col++], sizeof(szPassword));
  757.  
  758. if (!row[col])
  759. {
  760. *szMatrixCode = '\0';
  761. col++;
  762. }
  763. else
  764. {
  765. strlcpy(szMatrixCode, row[col++], sizeof(szMatrixCode));
  766. }
  767.  
  768. if (!row[col])
  769. {
  770. sys_err("error column %d", col);
  771. M2_DELETE(pinfo);
  772. break;
  773. }
  774.  
  775. strlcpy(szSocialID, row[col++], sizeof(szSocialID));
  776.  
  777. if (!row[col])
  778. {
  779. sys_err("error column %d", col);
  780. M2_DELETE(pinfo);
  781. break;
  782. }
  783.  
  784. str_to_number(dwID, row[col++]);
  785.  
  786. if (!row[col])
  787. {
  788. sys_err("error column %d", col);
  789. M2_DELETE(pinfo);
  790. break;
  791. }
  792.  
  793. strlcpy(szStatus, row[col++], sizeof(szStatus));
  794.  
  795. #ifdef __MULTI_LANGUAGE_SYSTEM__
  796. if (!row[col])
  797. {
  798. sys_err("error column %d", col);
  799. M2_DELETE(pinfo);
  800. break;
  801. }
  802. str_to_number(bLanguage, row[col++]);
  803. #endif
  804. BYTE bNotAvail = 0;
  805. str_to_number(bNotAvail, row[col++]);
  806.  
  807. int aiPremiumTimes[PREMIUM_MAX_NUM];
  808. memset(&aiPremiumTimes, 0, sizeof(aiPremiumTimes));
  809.  
  810. char szCreateDate[256] = "00000000";
  811.  
  812. {
  813. str_to_number(aiPremiumTimes[PREMIUM_EXP], row[col++]);
  814. str_to_number(aiPremiumTimes[PREMIUM_ITEM], row[col++]);
  815. str_to_number(aiPremiumTimes[PREMIUM_SAFEBOX], row[col++]);
  816. str_to_number(aiPremiumTimes[PREMIUM_AUTOLOOT], row[col++]);
  817. str_to_number(aiPremiumTimes[PREMIUM_FISH_MIND], row[col++]);
  818. str_to_number(aiPremiumTimes[PREMIUM_MARRIAGE_FAST], row[col++]);
  819. str_to_number(aiPremiumTimes[PREMIUM_GOLD], row[col++]);
  820.  
  821. {
  822. long retValue = 0;
  823. str_to_number(retValue, row[col]);
  824.  
  825. time_t create_time = retValue;
  826. struct tm * tm1;
  827. tm1 = localtime(&create_time);
  828. strftime(szCreateDate, 255, "%Y%m%d", tm1);
  829.  
  830. sys_log(0, "Create_Time %d %s", retValue, szCreateDate);
  831. sys_log(0, "Block Time %d ", strncmp(szCreateDate, g_stBlockDate.c_str(), 8));
  832. }
  833. }
  834.  
  835. int nPasswordDiff = strcmp(szEncrytPassword, szPassword);
  836.  
  837.  
  838. if (openid_server)
  839. {
  840. nPasswordDiff = 0;
  841. }
  842.  
  843. if (nPasswordDiff)
  844. {
  845. LoginFailure(d, "WRONGPWD");
  846. sys_log(0, " WRONGPWD");
  847. M2_DELETE(pinfo);
  848. }
  849. else if (bNotAvail)
  850. {
  851. LoginFailure(d, "NOTAVAIL");
  852. sys_log(0, " NOTAVAIL");
  853. M2_DELETE(pinfo);
  854. }
  855. else if (DESC_MANAGER::instance().FindByLoginName(pinfo->login))
  856. {
  857. LoginFailure(d, "ALREADY");
  858. sys_log(0, " ALREADY");
  859. M2_DELETE(pinfo);
  860. }
  861. else if(!CShutdownManager::Instance().CheckCorrectSocialID(szSocialID) && !test_server)
  862. {
  863. LoginFailure(d, "BADSCLID");
  864. sys_log(0, " BADSCLID");
  865. M2_DELETE(pinfo);
  866. }
  867. else if(CShutdownManager::Instance().CheckShutdownAge(szSocialID) && CShutdownManager::Instance().CheckShutdownTime())
  868. {
  869. LoginFailure(d, "AGELIMIT");
  870. sys_log(0, " AGELIMIT");
  871. M2_DELETE(pinfo);
  872. }
  873. else if (strcmp(szStatus, "OK"))
  874. {
  875. LoginFailure(d, szStatus);
  876. sys_log(0, " STATUS: %s", szStatus);
  877. M2_DELETE(pinfo);
  878. }
  879. #ifdef __MULTI_LANGUAGE_SYSTEM__
  880. else if (pinfo->bLanguage >= LOCALE_MAX_NUM)
  881. {
  882. LoginFailure(d, "INVLANG");
  883. sys_log(0, "Invalid language selected.");
  884. M2_DELETE(pinfo);
  885. }
  886. else if (!pinfo->bLanguage)
  887. {
  888. LoginFailure(d, "NOLANG");
  889. sys_log(0, "No language selected.");
  890. M2_DELETE(pinfo);
  891. }
  892. #endif
  893. else
  894. {
  895. if (LC_IsEurope())
  896. {
  897. if (strncmp(szCreateDate, g_stBlockDate.c_str(), 8) >= 0)
  898. {
  899. LoginFailure(d, "BLKLOGIN");
  900. sys_log(0, " BLKLOGIN");
  901. M2_DELETE(pinfo);
  902. break;
  903. }
  904.  
  905. char szQuery[1024];
  906. #ifdef __MULTI_LANGUAGE_SYSTEM__
  907. snprintf(szQuery, sizeof(szQuery), "UPDATE account SET last_play=NOW(), language=%u WHERE id=%u", pinfo->bLanguage, dwID);
  908. #else
  909. snprintf(szQuery, sizeof(szQuery), "UPDATE account SET last_play=NOW() WHERE id=%u", dwID);
  910. #endif
  911. std::auto_ptr<SQLMsg> msg( DBManager::instance().DirectQuery(szQuery) );
  912. }
  913.  
  914. TAccountTable & r = d->GetAccountTable();
  915.  
  916. r.id = dwID;
  917. trim_and_lower(pinfo->login, r.login, sizeof(r.login));
  918. strlcpy(r.passwd, pinfo->passwd, sizeof(r.passwd));
  919. strlcpy(r.social_id, szSocialID, sizeof(r.social_id));
  920. #ifdef __MULTI_LANGUAGE_SYSTEM__
  921. r.bLanguage = pinfo->bLanguage; // bLanguage;
  922. #endif
  923. DESC_MANAGER::instance().ConnectAccount(r.login, d);
  924.  
  925. d->SetMatrixCode(szMatrixCode);
  926.  
  927. if (!g_bBilling)
  928. {
  929. LoginPrepare(BILLING_FREE, 0, 0, d, pinfo->adwClientKey, aiPremiumTimes);
  930. //By SeMinZ
  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 mysql_hash_password(%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. mysql_hash_password(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() :
  1379. m_IsConnect(false)
  1380. {
  1381. }
  1382.  
  1383. bool AccountDB::IsConnected()
  1384. {
  1385. return m_IsConnect;
  1386. }
  1387.  
  1388. bool AccountDB::Connect(const char * host, const int port, const char * user, const char * pwd, const char * db)
  1389. {
  1390. m_IsConnect = m_sql_direct.Setup(host, user, pwd, db, "", true, port);
  1391.  
  1392. if (false == m_IsConnect)
  1393. {
  1394. fprintf(stderr, "cannot open direct sql connection to host: %s user: %s db: %s\n", host, user, db);
  1395. return false;
  1396. }
  1397.  
  1398. return m_IsConnect;
  1399. }
  1400.  
  1401. bool AccountDB::ConnectAsync(const char * host, const int port, const char * user, const char * pwd, const char * db, const char * locale)
  1402. {
  1403. m_sql.Setup(host, user, pwd, db, locale, false, port);
  1404. return true;
  1405. }
  1406.  
  1407. void AccountDB::SetLocale(const std::string & stLocale)
  1408. {
  1409. m_sql_direct.SetLocale(stLocale);
  1410. m_sql_direct.QueryLocaleSet();
  1411. }
  1412.  
  1413. SQLMsg* AccountDB::DirectQuery(const char * query)
  1414. {
  1415. return m_sql_direct.DirectQuery(query);
  1416. }
  1417.  
  1418. void AccountDB::AsyncQuery(const char* query)
  1419. {
  1420. m_sql.AsyncQuery(query);
  1421. }
  1422.  
  1423. void AccountDB::ReturnQuery(int iType, DWORD dwIdent, void * pvData, const char * c_pszFormat, ...)
  1424. {
  1425. char szQuery[4096];
  1426. va_list args;
  1427.  
  1428. va_start(args, c_pszFormat);
  1429. vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
  1430. va_end(args);
  1431.  
  1432. CReturnQueryInfo * p = M2_NEW CReturnQueryInfo;
  1433.  
  1434. p->iQueryType = QUERY_TYPE_RETURN;
  1435. p->iType = iType;
  1436. p->dwIdent = dwIdent;
  1437. p->pvData = pvData;
  1438.  
  1439. m_sql.ReturnQuery(szQuery, p);
  1440. }
  1441.  
  1442. SQLMsg * AccountDB::PopResult()
  1443. {
  1444. SQLMsg * p;
  1445.  
  1446. if (m_sql.PopResult(&p))
  1447. return p;
  1448.  
  1449. return NULL;
  1450. }
  1451.  
  1452. void AccountDB::Process()
  1453. {
  1454. SQLMsg* pMsg = NULL;
  1455.  
  1456. while ((pMsg = PopResult()))
  1457. {
  1458. CQueryInfo* qi = (CQueryInfo *) pMsg->pvUserData;
  1459.  
  1460. switch (qi->iQueryType)
  1461. {
  1462. case QUERY_TYPE_RETURN:
  1463. AnalyzeReturnQuery(pMsg);
  1464. break;
  1465. }
  1466. }
  1467.  
  1468. delete pMsg;
  1469. }
  1470.  
  1471. extern unsigned int g_uiSpamReloadCycle;
  1472.  
  1473. enum EAccountQID
  1474. {
  1475. QID_SPAM_DB,
  1476. };
  1477.  
  1478.  
  1479. static LPEVENT s_pkReloadSpamEvent = NULL;
  1480.  
  1481. EVENTINFO(reload_spam_event_info)
  1482. {
  1483. // used to send command
  1484. DWORD empty;
  1485. };
  1486.  
  1487. EVENTFUNC(reload_spam_event)
  1488. {
  1489. AccountDB::instance().ReturnQuery(QID_SPAM_DB, 0, NULL, "SELECT word, score FROM spam_db WHERE type='SPAM'");
  1490. return PASSES_PER_SEC(g_uiSpamReloadCycle);
  1491. }
  1492.  
  1493. // #define ENABLE_SPAMDB_REFRESH
  1494. void LoadSpamDB()
  1495. {
  1496. AccountDB::instance().ReturnQuery(QID_SPAM_DB, 0, NULL, "SELECT word, score FROM spam_db WHERE type='SPAM'");
  1497. #ifdef ENABLE_SPAMDB_REFRESH
  1498. if (NULL == s_pkReloadSpamEvent)
  1499. {
  1500. reload_spam_event_info* info = AllocEventInfo<reload_spam_event_info>();
  1501. s_pkReloadSpamEvent = event_create(reload_spam_event, info, PASSES_PER_SEC(g_uiSpamReloadCycle));
  1502. }
  1503. #endif
  1504. }
  1505.  
  1506. void CancelReloadSpamEvent() {
  1507. s_pkReloadSpamEvent = NULL;
  1508. }
  1509.  
  1510. void AccountDB::AnalyzeReturnQuery(SQLMsg * pMsg)
  1511. {
  1512. CReturnQueryInfo * qi = (CReturnQueryInfo *) pMsg->pvUserData;
  1513.  
  1514. switch (qi->iType)
  1515. {
  1516. case QID_SPAM_DB:
  1517. {
  1518. if (pMsg->Get()->uiNumRows > 0)
  1519. {
  1520. MYSQL_ROW row;
  1521.  
  1522. SpamManager::instance().Clear();
  1523.  
  1524. while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
  1525. SpamManager::instance().Insert(row[0], atoi(row[1]));
  1526. }
  1527. }
  1528. break;
  1529. }
  1530.  
  1531. M2_DELETE(qi);
  1532. }
  1533.  
  1534.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement