2022-03-05 12:44:06 +02:00
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include <sstream>
|
2022-03-05 19:59:39 +02:00
|
|
|
|
#include <common/billing.h>
|
|
|
|
|
#include <common/length.h>
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
#include "db.h"
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "desc_client.h"
|
|
|
|
|
#include "desc_manager.h"
|
|
|
|
|
#include "char.h"
|
|
|
|
|
#include "char_manager.h"
|
|
|
|
|
#include "item.h"
|
|
|
|
|
#include "item_manager.h"
|
|
|
|
|
#include "p2p.h"
|
|
|
|
|
#include "matrix_card.h"
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "login_data.h"
|
|
|
|
|
#include "locale_service.h"
|
|
|
|
|
#include "pcbang.h"
|
|
|
|
|
#include "spam.h"
|
|
|
|
|
|
|
|
|
|
extern std::string g_stBlockDate;
|
|
|
|
|
|
|
|
|
|
DBManager::DBManager() : m_bIsConnect(false)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DBManager::~DBManager()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DBManager::Connect(const char * host, const int port, const char * user, const char * pwd, const char * db)
|
|
|
|
|
{
|
|
|
|
|
if (m_sql.Setup(host, user, pwd, db, g_stLocale.c_str(), false, port))
|
|
|
|
|
m_bIsConnect = true;
|
|
|
|
|
|
|
|
|
|
if (!m_sql_direct.Setup(host, user, pwd, db, g_stLocale.c_str(), true, port))
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("cannot open direct sql connection to host {}", host);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
return m_bIsConnect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::Query(const char * c_pszFormat, ...)
|
|
|
|
|
{
|
|
|
|
|
char szQuery[4096];
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, c_pszFormat);
|
|
|
|
|
vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
m_sql.AsyncQuery(szQuery);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLMsg * DBManager::DirectQuery(const char * c_pszFormat, ...)
|
|
|
|
|
{
|
|
|
|
|
char szQuery[4096];
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, c_pszFormat);
|
|
|
|
|
vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
return m_sql_direct.DirectQuery(szQuery);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DBManager::IsConnected()
|
|
|
|
|
{
|
|
|
|
|
return m_bIsConnect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::ReturnQuery(int iType, DWORD dwIdent, void * pvData, const char * c_pszFormat, ...)
|
|
|
|
|
{
|
|
|
|
|
char szQuery[4096];
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, c_pszFormat);
|
|
|
|
|
vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
CReturnQueryInfo * p = M2_NEW CReturnQueryInfo;
|
|
|
|
|
|
|
|
|
|
p->iQueryType = QUERY_TYPE_RETURN;
|
|
|
|
|
p->iType = iType;
|
|
|
|
|
p->dwIdent = dwIdent;
|
|
|
|
|
p->pvData = pvData;
|
|
|
|
|
|
|
|
|
|
m_sql.ReturnQuery(szQuery, p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLMsg * DBManager::PopResult()
|
|
|
|
|
{
|
|
|
|
|
SQLMsg * p;
|
|
|
|
|
|
|
|
|
|
if (m_sql.PopResult(&p))
|
|
|
|
|
return p;
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::Process()
|
|
|
|
|
{
|
|
|
|
|
SQLMsg* pMsg = NULL;
|
|
|
|
|
|
|
|
|
|
while ((pMsg = PopResult()))
|
|
|
|
|
{
|
|
|
|
|
if( NULL != pMsg->pvUserData )
|
|
|
|
|
{
|
|
|
|
|
switch( reinterpret_cast<CQueryInfo*>(pMsg->pvUserData)->iQueryType )
|
|
|
|
|
{
|
|
|
|
|
case QUERY_TYPE_RETURN:
|
|
|
|
|
AnalyzeReturnQuery(pMsg);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case QUERY_TYPE_FUNCTION:
|
|
|
|
|
{
|
|
|
|
|
CFuncQueryInfo* qi = reinterpret_cast<CFuncQueryInfo*>( pMsg->pvUserData );
|
|
|
|
|
qi->f(pMsg);
|
|
|
|
|
M2_DELETE(qi);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case QUERY_TYPE_AFTER_FUNCTION:
|
|
|
|
|
{
|
|
|
|
|
CFuncAfterQueryInfo* qi = reinterpret_cast<CFuncAfterQueryInfo*>( pMsg->pvUserData );
|
|
|
|
|
qi->f();
|
|
|
|
|
M2_DELETE(qi);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete pMsg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CLoginData * DBManager::GetLoginData(DWORD dwKey)
|
|
|
|
|
{
|
|
|
|
|
std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(dwKey);
|
|
|
|
|
|
|
|
|
|
if (it == m_map_pkLoginData.end())
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return it->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::InsertLoginData(CLoginData * pkLD)
|
|
|
|
|
{
|
|
|
|
|
m_map_pkLoginData.insert(std::make_pair(pkLD->GetKey(), pkLD));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::DeleteLoginData(CLoginData * pkLD)
|
|
|
|
|
{
|
|
|
|
|
std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(pkLD->GetKey());
|
|
|
|
|
|
|
|
|
|
if (it == m_map_pkLoginData.end())
|
|
|
|
|
return;
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("DeleteLoginData {} {}", pkLD->GetLogin(), (void*) pkLD);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
mapLDBilling.erase(pkLD->GetLogin());
|
|
|
|
|
|
|
|
|
|
M2_DELETE(it->second);
|
|
|
|
|
m_map_pkLoginData.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::SetBilling(DWORD dwKey, bool bOn, bool bSkipPush)
|
|
|
|
|
{
|
|
|
|
|
std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.find(dwKey);
|
|
|
|
|
|
|
|
|
|
if (it == m_map_pkLoginData.end())
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("cannot find login key {}", dwKey);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CLoginData * ld = it->second;
|
|
|
|
|
|
|
|
|
|
itertype(mapLDBilling) it2 = mapLDBilling.find(ld->GetLogin());
|
|
|
|
|
|
|
|
|
|
if (it2 != mapLDBilling.end())
|
|
|
|
|
if (it2->second != ld)
|
|
|
|
|
DeleteLoginData(it2->second);
|
|
|
|
|
|
|
|
|
|
mapLDBilling.insert(std::make_pair(ld->GetLogin(), ld));
|
|
|
|
|
|
|
|
|
|
if (ld->IsBilling() && !bOn && !bSkipPush)
|
|
|
|
|
PushBilling(ld);
|
|
|
|
|
|
|
|
|
|
SendLoginPing(ld->GetLogin());
|
|
|
|
|
ld->SetBilling(bOn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::PushBilling(CLoginData * pkLD)
|
|
|
|
|
{
|
|
|
|
|
TUseTime t;
|
|
|
|
|
|
|
|
|
|
t.dwUseSec = (get_dword_time() - pkLD->GetLogonTime()) / 1000;
|
|
|
|
|
|
|
|
|
|
if (t.dwUseSec <= 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
pkLD->SetLogonTime();
|
2022-03-12 11:39:41 +02:00
|
|
|
|
int lRemainSecs = pkLD->GetRemainSecs() - t.dwUseSec;
|
2022-11-27 22:18:08 +02:00
|
|
|
|
pkLD->SetRemainSecs(std::max(0, lRemainSecs));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
t.dwLoginKey = pkLD->GetKey();
|
|
|
|
|
t.bBillType = pkLD->GetBillType();
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("BILLING: PUSH {} {} type {}", pkLD->GetLogin(), t.dwUseSec, t.bBillType);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (t.bBillType == BILLING_IP_FREE || t.bBillType == BILLING_IP_TIME || t.bBillType == BILLING_IP_DAY)
|
|
|
|
|
snprintf(t.szLogin, sizeof(t.szLogin), "%u", pkLD->GetBillID());
|
|
|
|
|
else
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(t.szLogin, pkLD->GetLogin(), sizeof(t.szLogin));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(t.szIP, pkLD->GetIP(), sizeof(t.szIP));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
m_vec_kUseTime.push_back(t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::FlushBilling(bool bForce)
|
|
|
|
|
{
|
|
|
|
|
if (bForce)
|
|
|
|
|
{
|
|
|
|
|
std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.begin();
|
|
|
|
|
|
|
|
|
|
while (it != m_map_pkLoginData.end())
|
|
|
|
|
{
|
|
|
|
|
CLoginData * pkLD = (it++)->second;
|
|
|
|
|
|
|
|
|
|
if (pkLD->IsBilling())
|
|
|
|
|
PushBilling(pkLD);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!m_vec_kUseTime.empty())
|
|
|
|
|
{
|
|
|
|
|
DWORD dwCount = 0;
|
|
|
|
|
|
|
|
|
|
std::vector<TUseTime>::iterator it = m_vec_kUseTime.begin();
|
|
|
|
|
|
|
|
|
|
while (it != m_vec_kUseTime.end())
|
|
|
|
|
{
|
|
|
|
|
TUseTime * p = &(*(it++));
|
|
|
|
|
|
|
|
|
|
// DISABLE_OLD_BILLING_CODE
|
|
|
|
|
if (!g_bBilling)
|
|
|
|
|
{
|
|
|
|
|
++dwCount;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Query("INSERT GameTimeLog (login, type, logon_time, logout_time, use_time, ip, server) "
|
|
|
|
|
"VALUES('%s', %u, DATE_SUB(NOW(), INTERVAL %u SECOND), NOW(), %u, '%s', '%s')",
|
|
|
|
|
p->szLogin, p->bBillType, p->dwUseSec, p->dwUseSec, p->szIP, g_stHostname.c_str());
|
|
|
|
|
// DISABLE_OLD_BILLING_CODE_END
|
|
|
|
|
|
|
|
|
|
switch (p->bBillType)
|
|
|
|
|
{
|
|
|
|
|
case BILLING_FREE:
|
|
|
|
|
case BILLING_IP_FREE:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case BILLING_DAY:
|
|
|
|
|
{
|
|
|
|
|
if (!bForce)
|
|
|
|
|
{
|
|
|
|
|
TUseTime * pInfo = M2_NEW TUseTime;
|
|
|
|
|
memcpy(pInfo, p, sizeof(TUseTime));
|
|
|
|
|
ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
|
|
|
|
|
"SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTime WHERE UserID='%s'", p->szLogin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case BILLING_TIME:
|
|
|
|
|
{
|
|
|
|
|
Query("UPDATE GameTime SET LimitTime=LimitTime-%u WHERE UserID='%s'", p->dwUseSec, p->szLogin);
|
|
|
|
|
|
|
|
|
|
if (!bForce)
|
|
|
|
|
{
|
|
|
|
|
TUseTime * pInfo = M2_NEW TUseTime;
|
|
|
|
|
memcpy(pInfo, p, sizeof(TUseTime));
|
|
|
|
|
ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
|
|
|
|
|
"SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTime WHERE UserID='%s'", p->szLogin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case BILLING_IP_DAY:
|
|
|
|
|
{
|
|
|
|
|
if (!bForce)
|
|
|
|
|
{
|
|
|
|
|
TUseTime * pInfo = M2_NEW TUseTime;
|
|
|
|
|
memcpy(pInfo, p, sizeof(TUseTime));
|
|
|
|
|
ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
|
|
|
|
|
"SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTimeIP WHERE ipid=%s", p->szLogin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case BILLING_IP_TIME:
|
|
|
|
|
{
|
|
|
|
|
Query("UPDATE GameTimeIP SET LimitTime=LimitTime-%u WHERE ipid=%s", p->dwUseSec, p->szLogin);
|
|
|
|
|
|
|
|
|
|
if (!bForce)
|
|
|
|
|
{
|
|
|
|
|
TUseTime * pInfo = M2_NEW TUseTime;
|
|
|
|
|
memcpy(pInfo, p, sizeof(TUseTime));
|
|
|
|
|
ReturnQuery(QID_BILLING_CHECK, 0, pInfo,
|
|
|
|
|
"SELECT UNIX_TIMESTAMP(LimitDt)-UNIX_TIMESTAMP(NOW()),LimitTime FROM GameTimeIP WHERE ipid=%s", p->szLogin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!bForce && ++dwCount >= 1000)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dwCount < m_vec_kUseTime.size())
|
|
|
|
|
{
|
|
|
|
|
int nNewSize = m_vec_kUseTime.size() - dwCount;
|
|
|
|
|
memcpy(&m_vec_kUseTime[0], &m_vec_kUseTime[dwCount], sizeof(TUseTime) * nNewSize);
|
|
|
|
|
m_vec_kUseTime.resize(nNewSize);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
m_vec_kUseTime.clear();
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("FLUSH_USE_TIME: count {}", dwCount);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_vec_kUseTime.size() < 10240)
|
|
|
|
|
{
|
|
|
|
|
DWORD dwCurTime = get_dword_time();
|
|
|
|
|
|
|
|
|
|
std::map<DWORD, CLoginData *>::iterator it = m_map_pkLoginData.begin();
|
|
|
|
|
|
|
|
|
|
while (it != m_map_pkLoginData.end())
|
|
|
|
|
{
|
|
|
|
|
CLoginData * pkLD = (it++)->second;
|
|
|
|
|
|
|
|
|
|
if (!pkLD->IsBilling())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
switch (pkLD->GetBillType())
|
|
|
|
|
{
|
|
|
|
|
case BILLING_IP_FREE:
|
|
|
|
|
case BILLING_FREE:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case BILLING_IP_DAY:
|
|
|
|
|
case BILLING_DAY:
|
|
|
|
|
case BILLING_IP_TIME:
|
|
|
|
|
case BILLING_TIME:
|
|
|
|
|
if (pkLD->GetRemainSecs() < 0)
|
|
|
|
|
{
|
|
|
|
|
DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
|
|
|
|
|
|
|
|
|
|
if (dwSecsConnected % 10 == 0)
|
|
|
|
|
SendBillingExpire(pkLD->GetLogin(), BILLING_DAY, 0, pkLD);
|
|
|
|
|
}
|
|
|
|
|
else if (pkLD->GetRemainSecs() <= 600) // if remain seconds lower than 10 minutes
|
|
|
|
|
{
|
|
|
|
|
DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
|
|
|
|
|
|
|
|
|
|
if (dwSecsConnected >= 60) // 60 second cycle
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("BILLING 1 {} remain {} connected secs {}",
|
2022-03-05 12:44:06 +02:00
|
|
|
|
pkLD->GetLogin(), pkLD->GetRemainSecs(), dwSecsConnected);
|
|
|
|
|
PushBilling(pkLD);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DWORD dwSecsConnected = (dwCurTime - pkLD->GetLogonTime()) / 1000;
|
|
|
|
|
|
|
|
|
|
if (dwSecsConnected > (DWORD) (pkLD->GetRemainSecs() - 600) || dwSecsConnected >= 600)
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("BILLING 2 {} remain {} connected secs {}",
|
2022-03-05 12:44:06 +02:00
|
|
|
|
pkLD->GetLogin(), pkLD->GetRemainSecs(), dwSecsConnected);
|
|
|
|
|
PushBilling(pkLD);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::CheckBilling()
|
|
|
|
|
{
|
|
|
|
|
std::vector<DWORD> vec;
|
|
|
|
|
vec.push_back(0); // ī<><C4AB>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>.
|
|
|
|
|
|
|
|
|
|
itertype(m_map_pkLoginData) it = m_map_pkLoginData.begin();
|
|
|
|
|
|
|
|
|
|
while (it != m_map_pkLoginData.end())
|
|
|
|
|
{
|
|
|
|
|
CLoginData * pkLD = (it++)->second;
|
|
|
|
|
|
|
|
|
|
if (pkLD->IsBilling())
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("BILLING: CHECK {}", pkLD->GetKey());
|
2022-03-05 12:44:06 +02:00
|
|
|
|
vec.push_back(pkLD->GetKey());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vec[0] = vec.size() - 1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20>ִ´<D6B4>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڽ<EFBFBD><DABD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϹǷ<CFB9> -1
|
|
|
|
|
db_clientdesc->DBPacket(HEADER_GD_BILLING_CHECK, 0, &vec[0], sizeof(DWORD) * vec.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::SendLoginPing(const char * c_pszLogin)
|
|
|
|
|
{
|
|
|
|
|
TPacketGGLoginPing ptog;
|
|
|
|
|
|
|
|
|
|
ptog.bHeader = HEADER_GG_LOGIN_PING;
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(ptog.szLogin, c_pszLogin, sizeof(ptog.szLogin));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (!g_pkAuthMasterDesc) // If I am master, broadcast to others
|
|
|
|
|
{
|
|
|
|
|
P2P_MANAGER::instance().Send(&ptog, sizeof(TPacketGGLoginPing));
|
|
|
|
|
}
|
|
|
|
|
else // If I am slave send login ping to master
|
|
|
|
|
{
|
|
|
|
|
g_pkAuthMasterDesc->Packet(&ptog, sizeof(TPacketGGLoginPing));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::SendAuthLogin(LPDESC d)
|
|
|
|
|
{
|
|
|
|
|
const TAccountTable & r = d->GetAccountTable();
|
|
|
|
|
|
|
|
|
|
CLoginData * pkLD = GetLoginData(d->GetLoginKey());
|
|
|
|
|
|
|
|
|
|
if (!pkLD)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
TPacketGDAuthLogin ptod;
|
|
|
|
|
ptod.dwID = r.id;
|
|
|
|
|
|
|
|
|
|
trim_and_lower(r.login, ptod.szLogin, sizeof(ptod.szLogin));
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(ptod.szSocialID, r.social_id, sizeof(ptod.szSocialID));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
ptod.dwLoginKey = d->GetLoginKey();
|
|
|
|
|
ptod.bBillType = pkLD->GetBillType();
|
|
|
|
|
ptod.dwBillID = pkLD->GetBillID();
|
|
|
|
|
|
2022-03-06 17:36:43 +02:00
|
|
|
|
memcpy(ptod.iPremiumTimes, pkLD->GetPremiumPtr(), sizeof(ptod.iPremiumTimes));
|
|
|
|
|
memcpy(&ptod.adwClientKey, pkLD->GetClientKey(), sizeof(DWORD) * 4);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
db_clientdesc->DBPacket(HEADER_GD_AUTH_LOGIN, d->GetHandle(), &ptod, sizeof(TPacketGDAuthLogin));
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("SendAuthLogin {} key {}", ptod.szLogin, ptod.dwID);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
SendLoginPing(r.login);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
void DBManager::LoginPrepare(BYTE bBillType, DWORD dwBillID, int lRemainSecs, LPDESC d, DWORD * pdwClientKey, int * paiPremiumTimes)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
const TAccountTable & r = d->GetAccountTable();
|
|
|
|
|
|
|
|
|
|
CLoginData * pkLD = M2_NEW CLoginData;
|
|
|
|
|
|
|
|
|
|
pkLD->SetKey(d->GetLoginKey());
|
|
|
|
|
pkLD->SetLogin(r.login);
|
|
|
|
|
pkLD->SetBillType(bBillType);
|
|
|
|
|
pkLD->SetBillID(dwBillID);
|
|
|
|
|
pkLD->SetRemainSecs(lRemainSecs);
|
|
|
|
|
pkLD->SetIP(d->GetHostName());
|
|
|
|
|
pkLD->SetClientKey(pdwClientKey);
|
|
|
|
|
|
|
|
|
|
if (paiPremiumTimes)
|
|
|
|
|
pkLD->SetPremium(paiPremiumTimes);
|
|
|
|
|
|
|
|
|
|
InsertLoginData(pkLD);
|
|
|
|
|
|
|
|
|
|
if (*d->GetMatrixCode())
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
unsigned int rows = 0, cols = 0;
|
2022-03-05 12:44:06 +02:00
|
|
|
|
MatrixCardRndCoordinate(rows, cols);
|
|
|
|
|
|
|
|
|
|
d->SetMatrixCardRowsAndColumns(rows, cols);
|
|
|
|
|
|
|
|
|
|
TPacketGCMatrixCard pm;
|
|
|
|
|
|
|
|
|
|
pm.bHeader = HEADER_GC_MATRIX_CARD;
|
|
|
|
|
pm.dwRows = rows;
|
|
|
|
|
pm.dwCols = cols;
|
|
|
|
|
|
|
|
|
|
d->Packet(&pm, sizeof(TPacketGCMatrixCard));
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("MATRIX_QUERY: {} {}{} {}{} {}{} {}{} {}",
|
2022-03-05 12:44:06 +02:00
|
|
|
|
r.login,
|
|
|
|
|
MATRIX_CARD_ROW(rows, 0) + 'A',
|
|
|
|
|
MATRIX_CARD_COL(cols, 0) + 1,
|
|
|
|
|
MATRIX_CARD_ROW(rows, 1) + 'A',
|
|
|
|
|
MATRIX_CARD_COL(cols, 1) + 1,
|
|
|
|
|
MATRIX_CARD_ROW(rows, 2) + 'A',
|
|
|
|
|
MATRIX_CARD_COL(cols, 2) + 1,
|
|
|
|
|
MATRIX_CARD_ROW(rows, 3) + 'A',
|
|
|
|
|
MATRIX_CARD_COL(cols, 3) + 1,
|
|
|
|
|
d->GetMatrixCode());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
SendAuthLogin(d);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GetGameTimeIP(MYSQL_RES * pRes, BYTE & bBillType, DWORD & dwBillID, int & seconds, const char * c_pszIP)
|
|
|
|
|
{
|
|
|
|
|
if (!pRes)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
MYSQL_ROW row = mysql_fetch_row(pRes);
|
|
|
|
|
int col = 0;
|
|
|
|
|
|
|
|
|
|
str_to_number(dwBillID, row[col++]);
|
|
|
|
|
|
|
|
|
|
int ip_start = 0;
|
|
|
|
|
str_to_number(ip_start, row[col++]);
|
|
|
|
|
|
|
|
|
|
int ip_end = 0;
|
|
|
|
|
str_to_number(ip_end, row[col++]);
|
|
|
|
|
|
|
|
|
|
int type = 0;
|
|
|
|
|
str_to_number(type, row[col++]);
|
|
|
|
|
|
|
|
|
|
str_to_number(seconds, row[col++]);
|
|
|
|
|
|
|
|
|
|
int day_seconds = 0;
|
|
|
|
|
str_to_number(day_seconds, row[col++]);
|
|
|
|
|
|
|
|
|
|
char szIP[MAX_HOST_LENGTH + 1];
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(szIP, c_pszIP, sizeof(szIP));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
char * p = strrchr(szIP, '.');
|
|
|
|
|
++p;
|
|
|
|
|
|
|
|
|
|
int ip_postfix = 0;
|
|
|
|
|
str_to_number(ip_postfix, p);
|
|
|
|
|
int valid_ip = false;
|
|
|
|
|
|
|
|
|
|
if (ip_start <= ip_postfix && ip_end >= ip_postfix)
|
|
|
|
|
valid_ip = true;
|
|
|
|
|
|
|
|
|
|
bBillType = BILLING_NONE;
|
|
|
|
|
|
|
|
|
|
if (valid_ip)
|
|
|
|
|
{
|
|
|
|
|
if (type == -1)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (type == 0)
|
|
|
|
|
bBillType = BILLING_IP_FREE;
|
|
|
|
|
else if (day_seconds > 0)
|
|
|
|
|
{
|
|
|
|
|
bBillType = BILLING_IP_DAY;
|
|
|
|
|
seconds = day_seconds;
|
|
|
|
|
}
|
|
|
|
|
else if (seconds > 0)
|
|
|
|
|
bBillType = BILLING_IP_TIME;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GetGameTime(MYSQL_RES * pRes, BYTE & bBillType, int & seconds)
|
|
|
|
|
{
|
|
|
|
|
if (!pRes)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
MYSQL_ROW row = mysql_fetch_row(pRes);
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("GetGameTime {} {} {}", row[0], row[1], row[2]);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
int type = 0;
|
|
|
|
|
str_to_number(type, row[0]);
|
|
|
|
|
str_to_number(seconds, row[1]);
|
|
|
|
|
int day_seconds = 0;
|
|
|
|
|
str_to_number(day_seconds, row[2]);
|
|
|
|
|
bBillType = BILLING_NONE;
|
|
|
|
|
|
|
|
|
|
if (type == -1)
|
|
|
|
|
return false;
|
|
|
|
|
else if (type == 0)
|
|
|
|
|
bBillType = BILLING_FREE;
|
|
|
|
|
else if (day_seconds > 0)
|
|
|
|
|
{
|
|
|
|
|
bBillType = BILLING_DAY;
|
|
|
|
|
seconds = day_seconds;
|
|
|
|
|
}
|
|
|
|
|
else if (seconds > 0)
|
|
|
|
|
bBillType = BILLING_TIME;
|
|
|
|
|
|
|
|
|
|
if (!g_bBilling)
|
|
|
|
|
bBillType = BILLING_FREE;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SendBillingExpire(const char * c_pszLogin, BYTE bBillType, int iSecs, CLoginData * pkLD)
|
|
|
|
|
{
|
|
|
|
|
TPacketBillingExpire ptod;
|
|
|
|
|
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(ptod.szLogin, c_pszLogin, sizeof(ptod.szLogin));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
ptod.bBillType = bBillType;
|
2022-11-27 22:18:08 +02:00
|
|
|
|
ptod.dwRemainSeconds = std::max(0, iSecs);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
db_clientdesc->DBPacket(HEADER_GD_BILLING_EXPIRE, 0, &ptod, sizeof(TPacketBillingExpire));
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("BILLING: EXPIRE {} type {} sec {} ptr {}", c_pszLogin, bBillType, iSecs, (void*) pkLD);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::AnalyzeReturnQuery(SQLMsg * pMsg)
|
|
|
|
|
{
|
|
|
|
|
CReturnQueryInfo * qi = (CReturnQueryInfo *) pMsg->pvUserData;
|
|
|
|
|
|
|
|
|
|
switch (qi->iType)
|
|
|
|
|
{
|
|
|
|
|
case QID_AUTH_LOGIN:
|
|
|
|
|
{
|
|
|
|
|
TPacketCGLogin3 * pinfo = (TPacketCGLogin3 *) qi->pvData;
|
|
|
|
|
LPDESC d = DESC_MANAGER::instance().FindByLoginKey(qi->dwIdent);
|
|
|
|
|
|
|
|
|
|
if (!d)
|
|
|
|
|
{
|
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
//<2F><>ġ <20><><EFBFBD><EFBFBD> - By SeMinZ
|
|
|
|
|
d->SetLogin(pinfo->login);
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("QID_AUTH_LOGIN: START {} {}", qi->dwIdent, (void*) get_pointer(d));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (pMsg->Get()->uiNumRows == 0)
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG(" NOID");
|
2022-03-06 17:36:43 +02:00
|
|
|
|
LoginFailure(d, "NOID");
|
|
|
|
|
M2_DELETE(pinfo);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
|
|
|
|
|
int col = 0;
|
|
|
|
|
|
|
|
|
|
// PASSWORD('%s'), password, securitycode, social_id, id, status
|
|
|
|
|
char szEncrytPassword[45 + 1];
|
|
|
|
|
char szPassword[45 + 1];
|
|
|
|
|
char szMatrixCode[MATRIX_CODE_MAX_LEN + 1];
|
|
|
|
|
char szSocialID[SOCIAL_ID_MAX_LEN + 1];
|
|
|
|
|
char szStatus[ACCOUNT_STATUS_MAX_LEN + 1];
|
|
|
|
|
DWORD dwID = 0;
|
|
|
|
|
|
|
|
|
|
if (!row[col])
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("error column {}", col);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(szEncrytPassword, row[col++], sizeof(szEncrytPassword));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (!row[col])
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("error column {}", col);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(szPassword, row[col++], sizeof(szPassword));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (!row[col])
|
|
|
|
|
{
|
|
|
|
|
*szMatrixCode = '\0';
|
|
|
|
|
col++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(szMatrixCode, row[col++], sizeof(szMatrixCode));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!row[col])
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("error column {}", col);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(szSocialID, row[col++], sizeof(szSocialID));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (!row[col])
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("error column {}", col);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
str_to_number(dwID, row[col++]);
|
|
|
|
|
|
|
|
|
|
if (!row[col])
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("error column {}", col);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(szStatus, row[col++], sizeof(szStatus));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
BYTE bNotAvail = 0;
|
|
|
|
|
str_to_number(bNotAvail, row[col++]);
|
|
|
|
|
|
|
|
|
|
int aiPremiumTimes[PREMIUM_MAX_NUM];
|
|
|
|
|
memset(&aiPremiumTimes, 0, sizeof(aiPremiumTimes));
|
|
|
|
|
|
|
|
|
|
char szCreateDate[256] = "00000000";
|
|
|
|
|
|
|
|
|
|
if (!g_iUseLocale)
|
|
|
|
|
{
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_EXP], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_ITEM], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_SAFEBOX], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_AUTOLOOT], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_FISH_MIND], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_MARRIAGE_FAST], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_GOLD], row[col++]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_EXP], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_ITEM], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_SAFEBOX], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_AUTOLOOT], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_FISH_MIND], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_MARRIAGE_FAST], row[col++]);
|
|
|
|
|
str_to_number(aiPremiumTimes[PREMIUM_GOLD], row[col++]);
|
|
|
|
|
|
|
|
|
|
if (LC_IsEurope() || test_server)
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
int retValue = 0;
|
2022-03-05 12:44:06 +02:00
|
|
|
|
str_to_number(retValue, row[col]);
|
|
|
|
|
|
|
|
|
|
time_t create_time = retValue;
|
|
|
|
|
struct tm * tm1;
|
|
|
|
|
tm1 = localtime(&create_time);
|
|
|
|
|
strftime(szCreateDate, 255, "%Y%m%d", tm1);
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("Create_Time {} {}", retValue, szCreateDate);
|
|
|
|
|
SPDLOG_DEBUG("Block Time {} ", strncmp(szCreateDate, g_stBlockDate.c_str(), 8));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int nPasswordDiff = strcmp(szEncrytPassword, szPassword);
|
|
|
|
|
|
|
|
|
|
if (true == LC_IsBrazil())
|
|
|
|
|
{
|
|
|
|
|
nPasswordDiff = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>й<EFBFBD>ȣ üũ<C3BC><C5A9> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nPasswordDiff)
|
|
|
|
|
{
|
|
|
|
|
LoginFailure(d, "WRONGPWD");
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG(" WRONGPWD");
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
}
|
|
|
|
|
else if (bNotAvail)
|
|
|
|
|
{
|
|
|
|
|
LoginFailure(d, "NOTAVAIL");
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG(" NOTAVAIL");
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
}
|
|
|
|
|
else if (DESC_MANAGER::instance().FindByLoginName(pinfo->login))
|
|
|
|
|
{
|
|
|
|
|
LoginFailure(d, "ALREADY");
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG(" ALREADY");
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
}
|
|
|
|
|
else if (strcmp(szStatus, "OK"))
|
|
|
|
|
{
|
|
|
|
|
LoginFailure(d, szStatus);
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG(" STATUS: {}", szStatus);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (LC_IsEurope())
|
|
|
|
|
{
|
|
|
|
|
//stBlockData >= 0 == <20><>¥<EFBFBD><C2A5> BlockDate <20><><EFBFBD><EFBFBD> <20>̷<EFBFBD>
|
|
|
|
|
if (strncmp(szCreateDate, g_stBlockDate.c_str(), 8) >= 0)
|
|
|
|
|
{
|
|
|
|
|
LoginFailure(d, "BLKLOGIN");
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG(" BLKLOGIN");
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char szQuery[1024];
|
|
|
|
|
snprintf(szQuery, sizeof(szQuery), "UPDATE account SET last_play=NOW() WHERE id=%u", dwID);
|
2022-03-06 00:01:03 +02:00
|
|
|
|
std::unique_ptr<SQLMsg> msg( DBManager::instance().DirectQuery(szQuery) );
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TAccountTable & r = d->GetAccountTable();
|
|
|
|
|
|
|
|
|
|
r.id = dwID;
|
|
|
|
|
trim_and_lower(pinfo->login, r.login, sizeof(r.login));
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(r.passwd, pinfo->passwd, sizeof(r.passwd));
|
|
|
|
|
strlcpy(r.social_id, szSocialID, sizeof(r.social_id));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
DESC_MANAGER::instance().ConnectAccount(r.login, d);
|
|
|
|
|
|
|
|
|
|
d->SetMatrixCode(szMatrixCode);
|
|
|
|
|
|
|
|
|
|
if (!g_bBilling)
|
|
|
|
|
{
|
|
|
|
|
LoginPrepare(BILLING_FREE, 0, 0, d, pinfo->adwClientKey, aiPremiumTimes);
|
|
|
|
|
//By SeMinZ
|
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("QID_AUTH_LOGIN: SUCCESS {}", pinfo->login);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case QID_BILLING_GET_TIME:
|
|
|
|
|
{
|
|
|
|
|
TPacketCGLogin3 * pinfo = (TPacketCGLogin3 *) qi->pvData;
|
|
|
|
|
LPDESC d = DESC_MANAGER::instance().FindByLoginKey(qi->dwIdent);
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("QID_BILLING_GET_TIME: START ident {} d {}", qi->dwIdent, (void*) get_pointer(d));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (d)
|
|
|
|
|
{
|
|
|
|
|
if (pMsg->Get()->uiNumRows == 0)
|
|
|
|
|
{
|
|
|
|
|
if (g_bBilling)
|
|
|
|
|
LoginFailure(d, "NOBILL");
|
|
|
|
|
else
|
|
|
|
|
LoginPrepare(BILLING_FREE, 0, 0, d, pinfo->adwClientKey);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int seconds = 0;
|
|
|
|
|
BYTE bBillType = BILLING_NONE;
|
|
|
|
|
|
|
|
|
|
if (!GetGameTime(pMsg->Get()->pSQLResult, bBillType, seconds))
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("QID_BILLING_GET_TIME: BLOCK");
|
2022-03-05 12:44:06 +02:00
|
|
|
|
LoginFailure(d, "BLOCK");
|
|
|
|
|
}
|
|
|
|
|
else if (bBillType == BILLING_NONE)
|
|
|
|
|
{
|
|
|
|
|
LoginFailure(d, "NOBILL");
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("QID_BILLING_GET_TIME: NO TIME");
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LoginPrepare(bBillType, 0, seconds, d, pinfo->adwClientKey);
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("QID_BILLING_GET_TIME: SUCCESS");
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case QID_BILLING_CHECK:
|
|
|
|
|
{
|
|
|
|
|
TUseTime * pinfo = (TUseTime *) qi->pvData;
|
|
|
|
|
int iRemainSecs = 0;
|
|
|
|
|
|
|
|
|
|
CLoginData * pkLD = NULL;
|
|
|
|
|
|
|
|
|
|
if (pMsg->Get()->uiNumRows > 0)
|
|
|
|
|
{
|
|
|
|
|
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
|
|
|
|
|
|
|
|
|
|
int iLimitDt = 0;
|
|
|
|
|
str_to_number(iLimitDt, row[0]);
|
|
|
|
|
|
|
|
|
|
int iLimitTime = 0;
|
|
|
|
|
str_to_number(iLimitTime, row[1]);
|
|
|
|
|
|
|
|
|
|
pkLD = GetLoginData(pinfo->dwLoginKey);
|
|
|
|
|
|
|
|
|
|
if (pkLD)
|
|
|
|
|
{
|
|
|
|
|
switch (pkLD->GetBillType())
|
|
|
|
|
{
|
|
|
|
|
case BILLING_TIME:
|
|
|
|
|
if (iLimitTime <= 600 && iLimitDt > 0)
|
|
|
|
|
{
|
|
|
|
|
iRemainSecs = iLimitDt;
|
|
|
|
|
pkLD->SetBillType(BILLING_DAY);
|
|
|
|
|
pinfo->bBillType = BILLING_DAY;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
iRemainSecs = iLimitTime;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case BILLING_IP_TIME:
|
|
|
|
|
if (iLimitTime <= 600 && iLimitDt > 0)
|
|
|
|
|
{
|
|
|
|
|
iRemainSecs = iLimitDt;
|
|
|
|
|
pkLD->SetBillType(BILLING_IP_DAY);
|
|
|
|
|
pinfo->bBillType = BILLING_IP_DAY;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
iRemainSecs = iLimitTime;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case BILLING_DAY:
|
|
|
|
|
case BILLING_IP_DAY:
|
|
|
|
|
iRemainSecs = iLimitDt;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pkLD->SetRemainSecs(iRemainSecs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-27 22:18:08 +02:00
|
|
|
|
SendBillingExpire(pinfo->szLogin, pinfo->bBillType, std::max(0, iRemainSecs), pkLD);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
M2_DELETE(pinfo);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case QID_SAFEBOX_SIZE:
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(qi->dwIdent);
|
|
|
|
|
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
if (pMsg->Get()->uiNumRows > 0)
|
|
|
|
|
{
|
|
|
|
|
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
|
|
|
|
|
int size = 0;
|
|
|
|
|
str_to_number(size, row[0]);
|
|
|
|
|
ch->SetSafeboxSize(SAFEBOX_PAGE_SIZE * size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case QID_LOTTO:
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(qi->dwIdent);
|
|
|
|
|
DWORD * pdw = (DWORD *) qi->pvData;
|
|
|
|
|
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
if (pMsg->Get()->uiAffectedRows == 0 || pMsg->Get()->uiAffectedRows == (uint32_t)-1)
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("GIVE LOTTO FAIL TO pid {}", ch->GetPlayerID());
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LPITEM pkItem = ch->AutoGiveItem(pdw[0], pdw[1]);
|
|
|
|
|
|
|
|
|
|
if (pkItem)
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("GIVE LOTTO SUCCESS TO {} (pid {})", ch->GetName(), qi->dwIdent);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
//ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ȹ<><C8B9>: %s"), pkItem->GetName());
|
|
|
|
|
|
|
|
|
|
pkItem->SetSocket(0, pMsg->Get()->uiInsertID);
|
|
|
|
|
pkItem->SetSocket(1, pdw[2]);
|
|
|
|
|
}
|
|
|
|
|
else
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("GIVE LOTTO FAIL2 TO pid {}", ch->GetPlayerID());
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
M2_DELETE_ARRAY(pdw);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// BLOCK_CHAT
|
|
|
|
|
case QID_BLOCK_CHAT_LIST:
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(qi->dwIdent);
|
|
|
|
|
|
|
|
|
|
if (ch == NULL)
|
|
|
|
|
break;
|
|
|
|
|
if (pMsg->Get()->uiNumRows)
|
|
|
|
|
{
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
|
|
|
|
|
{
|
|
|
|
|
ch->ChatPacket(CHAT_TYPE_INFO, "%s %s sec", row[0], row[1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ch->ChatPacket(CHAT_TYPE_INFO, "No one currently blocked.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
// END_OF_BLOCK_CHAT
|
|
|
|
|
|
|
|
|
|
// PCBANG_IP_LIST
|
|
|
|
|
case QID_PCBANG_IP_LIST_CHECK:
|
|
|
|
|
{
|
|
|
|
|
const std::string PCBANG_IP_TABLE_NAME("pcbang_ip");
|
|
|
|
|
|
|
|
|
|
if (pMsg->Get()->uiNumRows > 0)
|
|
|
|
|
{
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
bool isFinded = false;
|
|
|
|
|
|
|
|
|
|
while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
|
|
|
|
|
{
|
|
|
|
|
const char* c_szName = row[0];
|
|
|
|
|
const char* c_szUpdateTime = row[12];
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_TRACE("{}:{}", c_szName, c_szUpdateTime);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (PCBANG_IP_TABLE_NAME == c_szName)
|
|
|
|
|
{
|
|
|
|
|
isFinded = true;
|
|
|
|
|
|
|
|
|
|
static std::string s_stLastTime;
|
|
|
|
|
if (s_stLastTime != c_szUpdateTime)
|
|
|
|
|
{
|
|
|
|
|
s_stLastTime = c_szUpdateTime;
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("'{}' mysql table is UPDATED({})", PCBANG_IP_TABLE_NAME, c_szUpdateTime);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
ReturnQuery(QID_PCBANG_IP_LIST_SELECT, 0, NULL, "SELECT pcbang_id, ip FROM %s;", PCBANG_IP_TABLE_NAME.c_str());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("'{}' mysql table is NOT updated({})", PCBANG_IP_TABLE_NAME, c_szUpdateTime);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isFinded)
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("'{}' mysql table CANNOT FIND", PCBANG_IP_TABLE_NAME);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (test_server)
|
|
|
|
|
{
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("'{}' mysql table is NOT EXIST", PCBANG_IP_TABLE_NAME);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case QID_PCBANG_IP_LIST_SELECT:
|
|
|
|
|
{
|
|
|
|
|
if (pMsg->Get()->uiNumRows > 0)
|
|
|
|
|
{
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
|
|
|
|
|
while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
|
|
|
|
|
{
|
|
|
|
|
CPCBangManager::instance().InsertIP(row[0], row[1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-30 22:15:54 +02:00
|
|
|
|
else
|
|
|
|
|
SPDLOG_TRACE("PCBANG_IP_LIST is EMPTY");
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// END_OF_PCBANG_IP_LIST
|
|
|
|
|
|
|
|
|
|
default:
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_ERROR("FATAL ERROR!!! Unhandled return query id {}", qi->iType);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
M2_DELETE(qi);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::SendMoneyLog(BYTE type, DWORD vnum, int gold)
|
|
|
|
|
{
|
|
|
|
|
if (!gold)
|
|
|
|
|
return;
|
|
|
|
|
TPacketMoneyLog p;
|
|
|
|
|
p.type = type;
|
|
|
|
|
p.vnum = vnum;
|
|
|
|
|
p.gold = gold;
|
|
|
|
|
db_clientdesc->DBPacket(HEADER_GD_MONEY_LOG, 0, &p, sizeof(p));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VCardUse(LPCHARACTER CardOwner, LPCHARACTER CardTaker, LPITEM item)
|
|
|
|
|
{
|
|
|
|
|
TPacketGDVCard p;
|
|
|
|
|
|
|
|
|
|
p.dwID = item->GetSocket(0);
|
2023-05-01 08:10:00 +03:00
|
|
|
|
strlcpy(p.szSellCharacter, CardOwner->GetName(), sizeof(p.szSellCharacter));
|
|
|
|
|
strlcpy(p.szSellAccount, CardOwner->GetDesc()->GetAccountTable().login, sizeof(p.szSellAccount));
|
|
|
|
|
strlcpy(p.szBuyCharacter, CardTaker->GetName(), sizeof(p.szBuyCharacter));
|
|
|
|
|
strlcpy(p.szBuyAccount, CardTaker->GetDesc()->GetAccountTable().login, sizeof(p.szBuyAccount));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
db_clientdesc->DBPacket(HEADER_GD_VCARD, 0, &p, sizeof(TPacketGDVCard));
|
|
|
|
|
|
|
|
|
|
CardTaker->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d<><64><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ð<EFBFBD><C3B0><EFBFBD> <20>߰<EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>. (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ %d)"), item->GetSocket(1) / 60, item->GetSocket(0));
|
|
|
|
|
|
|
|
|
|
LogManager::instance().VCardLog(p.dwID, CardTaker->GetX(), CardTaker->GetY(), g_stHostname.c_str(),
|
|
|
|
|
CardOwner->GetName(), CardOwner->GetDesc()->GetHostName(),
|
|
|
|
|
CardTaker->GetName(), CardTaker->GetDesc()->GetHostName());
|
|
|
|
|
|
|
|
|
|
ITEM_MANAGER::instance().RemoveItem(item);
|
|
|
|
|
|
2023-12-30 22:15:54 +02:00
|
|
|
|
SPDLOG_DEBUG("VCARD_TAKE: {} {} -> {}", p.dwID, CardOwner->GetName(), CardTaker->GetName());
|
2022-03-05 12:44:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DBManager::StopAllBilling()
|
|
|
|
|
{
|
|
|
|
|
for (itertype(m_map_pkLoginData) it = m_map_pkLoginData.begin(); it != m_map_pkLoginData.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
SetBilling(it->first, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t DBManager::EscapeString(char* dst, size_t dstSize, const char *src, size_t srcSize)
|
|
|
|
|
{
|
|
|
|
|
return m_sql_direct.EscapeString(dst, dstSize, src, srcSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Common SQL
|
|
|
|
|
//
|
|
|
|
|
AccountDB::AccountDB() :
|
|
|
|
|
m_IsConnect(false)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AccountDB::IsConnected()
|
|
|
|
|
{
|
|
|
|
|
return m_IsConnect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AccountDB::Connect(const char * host, const int port, const char * user, const char * pwd, const char * db)
|
|
|
|
|
{
|
2023-12-30 10:30:52 +02:00
|
|
|
|
m_IsConnect = m_sql_direct.Setup(host, user, pwd, db, nullptr, true, port);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
if (false == m_IsConnect)
|
|
|
|
|
{
|
2023-12-30 10:30:52 +02:00
|
|
|
|
SPDLOG_ERROR("cannot open direct sql connection to host: {} user: {} db: {}", host, user, db);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m_IsConnect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AccountDB::ConnectAsync(const char * host, const int port, const char * user, const char * pwd, const char * db, const char * locale)
|
|
|
|
|
{
|
|
|
|
|
m_sql.Setup(host, user, pwd, db, locale, false, port);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AccountDB::SetLocale(const std::string & stLocale)
|
|
|
|
|
{
|
|
|
|
|
m_sql_direct.SetLocale(stLocale);
|
|
|
|
|
m_sql_direct.QueryLocaleSet();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLMsg* AccountDB::DirectQuery(const char * query)
|
|
|
|
|
{
|
|
|
|
|
return m_sql_direct.DirectQuery(query);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AccountDB::AsyncQuery(const char* query)
|
|
|
|
|
{
|
|
|
|
|
m_sql.AsyncQuery(query);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AccountDB::ReturnQuery(int iType, DWORD dwIdent, void * pvData, const char * c_pszFormat, ...)
|
|
|
|
|
{
|
|
|
|
|
char szQuery[4096];
|
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
|
|
va_start(args, c_pszFormat);
|
|
|
|
|
vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
CReturnQueryInfo * p = M2_NEW CReturnQueryInfo;
|
|
|
|
|
|
|
|
|
|
p->iQueryType = QUERY_TYPE_RETURN;
|
|
|
|
|
p->iType = iType;
|
|
|
|
|
p->dwIdent = dwIdent;
|
|
|
|
|
p->pvData = pvData;
|
|
|
|
|
|
|
|
|
|
m_sql.ReturnQuery(szQuery, p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLMsg * AccountDB::PopResult()
|
|
|
|
|
{
|
|
|
|
|
SQLMsg * p;
|
|
|
|
|
|
|
|
|
|
if (m_sql.PopResult(&p))
|
|
|
|
|
return p;
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AccountDB::Process()
|
|
|
|
|
{
|
|
|
|
|
SQLMsg* pMsg = NULL;
|
|
|
|
|
|
|
|
|
|
while ((pMsg = PopResult()))
|
|
|
|
|
{
|
|
|
|
|
CQueryInfo* qi = (CQueryInfo *) pMsg->pvUserData;
|
|
|
|
|
|
|
|
|
|
switch (qi->iQueryType)
|
|
|
|
|
{
|
|
|
|
|
case QUERY_TYPE_RETURN:
|
|
|
|
|
AnalyzeReturnQuery(pMsg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete pMsg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern unsigned int g_uiSpamReloadCycle;
|
|
|
|
|
|
|
|
|
|
enum EAccountQID
|
|
|
|
|
{
|
|
|
|
|
QID_SPAM_DB,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 10<31>и<EFBFBD><D0B8><EFBFBD> <20><><EFBFBD>ε<EFBFBD>
|
|
|
|
|
static LPEVENT s_pkReloadSpamEvent = NULL;
|
|
|
|
|
|
|
|
|
|
EVENTINFO(reload_spam_event_info)
|
|
|
|
|
{
|
|
|
|
|
// used to send command
|
|
|
|
|
DWORD empty;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
EVENTFUNC(reload_spam_event)
|
|
|
|
|
{
|
|
|
|
|
AccountDB::instance().ReturnQuery(QID_SPAM_DB, 0, NULL, "SELECT word, score FROM spam_db WHERE type='SPAM'");
|
|
|
|
|
return PASSES_PER_SEC(g_uiSpamReloadCycle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadSpamDB()
|
|
|
|
|
{
|
|
|
|
|
AccountDB::instance().ReturnQuery(QID_SPAM_DB, 0, NULL, "SELECT word, score FROM spam_db WHERE type='SPAM'");
|
|
|
|
|
|
|
|
|
|
if (NULL == s_pkReloadSpamEvent)
|
|
|
|
|
{
|
|
|
|
|
reload_spam_event_info* info = AllocEventInfo<reload_spam_event_info>();
|
|
|
|
|
s_pkReloadSpamEvent = event_create(reload_spam_event, info, PASSES_PER_SEC(g_uiSpamReloadCycle));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CancelReloadSpamEvent() {
|
|
|
|
|
s_pkReloadSpamEvent = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AccountDB::AnalyzeReturnQuery(SQLMsg * pMsg)
|
|
|
|
|
{
|
|
|
|
|
CReturnQueryInfo * qi = (CReturnQueryInfo *) pMsg->pvUserData;
|
|
|
|
|
|
|
|
|
|
switch (qi->iType)
|
|
|
|
|
{
|
|
|
|
|
case QID_SPAM_DB:
|
|
|
|
|
{
|
|
|
|
|
if (pMsg->Get()->uiNumRows > 0)
|
|
|
|
|
{
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
|
|
|
|
|
SpamManager::instance().Clear();
|
|
|
|
|
|
|
|
|
|
while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
|
|
|
|
|
SpamManager::instance().Insert(row[0], atoi(row[1]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
M2_DELETE(qi);
|
|
|
|
|
}
|