- Katılım
- 26 Eki 2021
- Konular
- 196
- Mesajlar
- 910
- Çözüm
- 6
- Online süresi
- 3mo 6d
- Reaksiyon Skoru
- 973
- Altın Konu
- 39
- Başarım Puanı
- 184
- Yaş
- 28
- MmoLira
- 5,307
- DevLira
- 36
HERAKLES Otomatik Avlı kalıcı sunucu. 19 Haziran'da açılıyor. Atius & Wizard güvencesiyle hemen kayıt ol, ön kayıt ödülleri aktif. HEMEN TIKLA!
Bu sistem, oyuncuların bazı özel karakterler dahil olmak üzere 24 karaktere kadar uzunlukta isimler kullanmasına olanak tanıyor — ekran görüntüsünde örnek olarak görüldüğü gibi.
Aşağıdaki özel karakterlere izin veriliyor:
SQL sorguları açısından kritik olabilecek tüm noktaları yakaladığımı düşünüyorum — ama olası açıkları tespit etmek için buradaki kolektif zekaya (topluluğun bilgisine) güveniyorum.
Sorun veya benzeri durumlar olursa lütfen burada birbirinize yardım edin.
Not:Oyuncu adlarıyla ilgili olan GM komutları, örneğin "/t", oyuncu adı tırnak işaretleri içine alındığı sürece herhangi bir değişiklik yapılmadan çalışması gerekir.
Define ekle :
Code: Userinterface/StdAfx.h
Code: locale/ui/createcharacterwindow.py
Code: uiscript/inputdialog.py
Code: uiscript/createcharacterwindow.py
SERVER
Code: common/service.h (CommonDefines.h)
Code: game/locale_service.cpp
Code: game/log.cpp
Code: game/messenger_manager.cpp
Code: game/questlua_pc.cpp
Code: db/ClientManagerLogin.cpp
Code: db/ClientManagerPlayer.cpp
Aşağıdaki özel karakterlere izin veriliyor:
- Boşluk
- Alt çizgi
- Tire
- Nokta
- İki nokta üst üste
- Tek tırnak işareti
- Almanca umlaut karakterleri (Ä, Ö, Ü, ß)
SQL sorguları açısından kritik olabilecek tüm noktaları yakaladığımı düşünüyorum — ama olası açıkları tespit etmek için buradaki kolektif zekaya (topluluğun bilgisine) güveniyorum.
Sorun veya benzeri durumlar olursa lütfen burada birbirinize yardım edin.
Not:Oyuncu adlarıyla ilgili olan GM komutları, örneğin "/t", oyuncu adı tırnak işaretleri içine alındığı sürece herhangi bir değişiklik yapılmadan çalışması gerekir.
Define ekle :
Kod:
#define ENABLE_EXTENDED_PLAYER_NAMES //Enable extended character names (longer names and special chars)
Code: Userinterface/StdAfx.h
Kod:
//Replace this:
#if defined(LOCALE_SERVICE_JAPAN)
PLAYER_NAME_MAX_LEN = 16,
#else
PLAYER_NAME_MAX_LEN = 12,
#endif
//With this:
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
PLAYER_NAME_MAX_LEN = CHARACTER_NAME_MAX_LEN,
#else
#if defined(LOCALE_SERVICE_JAPAN)
PLAYER_NAME_MAX_LEN = 16,
#else
PLAYER_NAME_MAX_LEN = 12,
#endif
#endif
Code: locale/ui/createcharacterwindow.py
Kod:
//Add new import at the top of the file
import chr
//Find (should only appear once in "character_name_value":
"input_limit" : 12,
//Replace with:
"input_limit" : chr.PLAYER_NAME_MAX_LEN,
Code: uiscript/inputdialog.py
Kod:
//Add new import at the top of the file
import chr
//Find:
"input_limit" : 12,
//Replace with:
"input_limit" : chr.PLAYER_NAME_MAX_LEN,
Code: uiscript/createcharacterwindow.py
Kod:
//same changes as in locale/ui
import chr
[...]
"input_limit" : 12, -> "input_limit" : chr.PLAYER_NAME_MAX_LEN,
SERVER
Code: common/service.h (CommonDefines.h)
Kod:
#define ENABLE_EXTENDED_PLAYER_NAMES //Enable extended character names (longer names and special chars)
Code: game/locale_service.cpp
Kod:
//Find this function:
int check_name_alphabet(const char* str)
//Change or replace the method so it looks like this:
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
bool is_valid_name_char(unsigned char c)
{
//Checking for alphanumeric characters, space, underscore, hyphen, dot, colon and apostrophe
if (isalnum(c) || c == ' ' || c == '_' || c == '-' || c == '.' || c == ':' || c == '\'')
return true;
//Checking for german special characters (in order):
// 0xE4 (ä)
// 0xF6 (ö)
// 0xFC (ü)
// 0xDF (ß)
if (c == 0xE4 || c == 0xF6 || c == 0xFC || c == 0xDF)
return true;
return false;
}
int check_name_alphabet(const char* str)
{
if (!str || !*str)
return 0;
const char* start = str;
size_t len = strlen(start);
//Name has to be between 2 and CHARACTER_NAME_MAX_LEN characters long
if (len < 2 || len > CHARACTER_NAME_MAX_LEN)
return 0;
//check for leading and trailing spaces
if ((isspace(static_cast<unsigned char>(start[0]))) || (isspace(static_cast<unsigned char>(start[len - 1]))))
return 0;
bool has_non_space = false;
bool last_was_space = false;
for (const unsigned char* tmp = (const unsigned char*)start; *tmp; ++tmp)
{
if (!is_valid_name_char(*tmp))
return 0;
if (*tmp == ' ')
{
if (last_was_space)
return 0; // consecutive spaces are not allowed
last_was_space = true; // mark that the last character was a space
}
else
{
has_non_space = true; // mark that we have at least one non-space character
last_was_space = false; // reset space marker
}
}
if (!has_non_space)
return 0; // if there are no non-space characters, return 0
return check_name_independent(start);
}
#else
int check_name_alphabet(const char* str)
{
const char* tmp;
if (!str || !*str)
return 0;
if (strlen(str) < 2)
return 0;
for (tmp = str; *tmp; ++tmp)
{
// ¾ËÆÄºª°ú ¼öÀÚ¸¸ Çã¿ë
if (isdigit(*tmp) || isalpha(*tmp))
continue;
else
return 0;
}
return check_name_independent(str);
}
#endif
Code: game/log.cpp
Kod:
//If any of the methods are not existing in your log.cpp, ignore them..
//Change or replace the following functions:
//Hacklog
void LogManager::HackLog(const char * c_pszHackName, const char * c_pszLogin, const char * c_pszName, const char * c_pszIP)
{
m_sql.EscapeString(__escape_hint, sizeof(__escape_hint), c_pszHackName, strlen(c_pszHackName));
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapedName[CHARACTER_NAME_MAX_LEN * 2 + 1];
size_t nameLen = strnlen(c_pszName, CHARACTER_NAME_MAX_LEN);
m_sql.EscapeString(escapedName, sizeof(escapedName), c_pszName, nameLen);
Query("INSERT INTO hack_log (time, login, name, ip, server, why) VALUES(NOW(), '%s', '%s', '%s', '%s', '%s')", c_pszLogin, escapedName, c_pszIP, g_stHostname.c_str(), __escape_hint);
#else
Query("INSERT INTO hack_log (time, login, name, ip, server, why) VALUES(NOW(), '%s', '%s', '%s', '%s', '%s')", c_pszLogin, c_pszName, c_pszIP, g_stHostname.c_str(), __escape_hint);
#endif
}
//HackCRCLog
void LogManager::HackCRCLog(const char * c_pszHackName, const char * c_pszLogin, const char * c_pszName, const char * c_pszIP, DWORD dwCRC)
{
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
m_sql.EscapeString(__escape_hint, sizeof(__escape_hint), c_pszHackName, strlen(c_pszHackName));
char escapedName[CHARACTER_NAME_MAX_LEN * 2 + 1];
size_t nameLen = strnlen(c_pszName, CHARACTER_NAME_MAX_LEN);
m_sql.EscapeString(escapedName, sizeof(escapedName), c_pszName, nameLen);
Query("INSERT INTO hack_crc_log (time, login, name, ip, server, why, crc) VALUES(NOW(), '%s', '%s', '%s', '%s', '%s', %u)", c_pszLogin, escapedName, c_pszIP, g_stHostname.c_str(), __escape_hint, dwCRC);
#else
Query("INSERT INTO hack_crc_log (time, login, name, ip, server, why, crc) VALUES(NOW(), '%s', '%s', '%s', '%s', '%s', %u)", c_pszLogin, c_pszName, c_pszIP, g_stHostname.c_str(), c_pszHackName, dwCRC);
#endif
}
//ChangeNameLog
void LogManager::ChangeNameLog(DWORD pid, const char *old_name, const char *new_name, const char *ip)
{
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapeOldName[CHARACTER_NAME_MAX_LEN * 2 + 1];
size_t oldNameLen = strnlen(old_name, CHARACTER_NAME_MAX_LEN);
m_sql.EscapeString(escapeOldName, sizeof(escapeOldName), old_name, oldNameLen);
char escapeNewName[CHARACTER_NAME_MAX_LEN * 2 + 1];
size_t newNameLen = strnlen(new_name, CHARACTER_NAME_MAX_LEN);
m_sql.EscapeString(escapeNewName, sizeof(escapeNewName), new_name, newNameLen);
Query("INSERT DELAYED INTO change_name%s (pid, old_name, new_name, time, ip) "
"VALUES(%u, '%s', '%s', NOW(), '%s') ",
get_table_postfix(), pid, escapeOldName, escapeNewName, ip);
#else
Query("INSERT DELAYED INTO change_name%s (pid, old_name, new_name, time, ip) "
"VALUES(%u, '%s', '%s', NOW(), '%s') ",
get_table_postfix(), pid, old_name, new_name, ip);
#endif
}
//GMCommandLog
void LogManager::GMCommandLog(DWORD dwPID, const char* szName, const char* szIP, BYTE byChannel, const char* szCommand)
{
m_sql.EscapeString(__escape_hint, sizeof(__escape_hint), szCommand, strlen(szCommand));
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapeName[CHARACTER_NAME_MAX_LEN * 2 + 1];
size_t nameLen = strnlen(szName, CHARACTER_NAME_MAX_LEN);
m_sql.EscapeString(escapeName, sizeof(escapeName), szName, nameLen);
Query("INSERT DELAYED INTO command_log%s (userid, server, ip, port, username, command, date ) "
"VALUES(%u, 999, '%s', %u, '%s', '%s', NOW()) ",
get_table_postfix(), dwPID, szIP, byChannel, escapeName, __escape_hint);
#else
Query("INSERT DELAYED INTO command_log%s (userid, server, ip, port, username, command, date ) "
"VALUES(%u, 999, '%s', %u, '%s', '%s', NOW()) ",
get_table_postfix(), dwPID, szIP, byChannel, szName, __escape_hint);
#endif
}
//LevelLog
void LogManager::LevelLog(LPCHARACTER pChar, unsigned int level, unsigned int playhour)
{
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapedName[CHARACTER_NAME_MAX_LEN * 2 + 1];
m_sql.EscapeString(escapedName, sizeof(escapedName), pChar->GetName(), strlen(pChar->GetName()));
#endif
if (true == LC_IsEurope())
{
DWORD aid = 0;
if (NULL != pChar->GetDesc())
{
aid = pChar->GetDesc()->GetAccountTable().id;
}
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
Query("REPLACE INTO levellog%s (name, level, time, account_id, pid, playtime) VALUES('%s', %u, NOW(), %u, %u, %d)",
get_table_postfix(), escapedName, level, aid, pChar->GetPlayerID(), playhour);
#else
Query("REPLACE INTO levellog%s (name, level, time, account_id, pid, playtime) VALUES('%s', %u, NOW(), %u, %u, %d)",
get_table_postfix(), pChar->GetName(), level, aid, pChar->GetPlayerID(), playhour);
#endif
}
else
{
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
Query("REPLACE INTO levellog%s (name, level, time, playtime) VALUES('%s', %u, NOW(), %d)",
get_table_postfix(), escapedName, level, playhour);
#else
Query("REPLACE INTO levellog%s (name, level, time, playtime) VALUES('%s', %u, NOW(), %d)",
get_table_postfix(), pChar->GetName(), level, playhour);
#endif
}
}
//VCardLog
void LogManager::VCardLog(DWORD vcard_id, DWORD x, DWORD y, const char * hostname, const char * giver_name, const char * giver_ip, const char * taker_name, const char * taker_ip)
{
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapedGiverName[CHARACTER_NAME_MAX_LEN * 2 + 1];
m_sql.EscapeString(escapedGiverName, sizeof(escapedGiverName), giver_name, strlen(giver_name));
char escapedTakerName[CHARACTER_NAME_MAX_LEN * 2 + 1];
m_sql.EscapeString(escapedTakerName, sizeof(escapedTakerName), taker_name, strlen(taker_name));
Query("INSERT DELAYED INTO vcard_log (vcard_id, x, y, hostname, giver_name, giver_ip, taker_name, taker_ip) VALUES(%u, %u, %u, '%s', '%s', '%s', '%s', '%s')",
vcard_id, x, y, hostname, escapedGiverName, giver_ip, escapedGiverName, taker_ip);
#else
Query("INSERT DELAYED INTO vcard_log (vcard_id, x, y, hostname, giver_name, giver_ip, taker_name, taker_ip) VALUES(%u, %u, %u, '%s', '%s', '%s', '%s', '%s')",
vcard_id, x, y, hostname, giver_name, giver_ip, taker_name, taker_ip);
#endif
}
Code: game/messenger_manager.cpp
Kod:
//Change or replace the following functions:
//MessengerManager::Login
void MessengerManager::Login(MessengerManager::keyA account)
{
if (m_set_loginAccount.find(account) != m_set_loginAccount.end())
return;
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapedAccount[CHARACTER_NAME_MAX_LEN * 2 + 1];
DBManager::instance().EscapeString(escapedAccount, sizeof(escapedAccount), account.c_str(), account.length());
DBManager::instance().FuncQuery(std::bind(&MessengerManager::LoadList, this, std::placeholders::_1),
"SELECT account, companion FROM messenger_list%s WHERE account='%s'", get_table_postfix(), escapedAccount);
#else
DBManager::instance().FuncQuery(std::bind(&MessengerManager::LoadList, this, std::placeholders::_1),
"SELECT account, companion FROM messenger_list%s WHERE account='%s'", get_table_postfix(), account.c_str());
#endif
m_set_loginAccount.insert(account);
}
//MessengerManager::AddToList
void MessengerManager::AddToList(MessengerManager::keyA account, MessengerManager::keyA companion)
{
if (companion.size() == 0)
return;
if (m_Relation[account].find(companion) != m_Relation[account].end())
return;
sys_log(0, "Messenger Add %s %s", account.c_str(), companion.c_str());
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char companionEscaped[CHARACTER_NAME_MAX_LEN * 2 + 1];
DBManager::instance().EscapeString(companionEscaped, sizeof(companionEscaped), companion.c_str(), companion.length());
char accountEscaped[CHARACTER_NAME_MAX_LEN * 2 + 1];
DBManager::instance().EscapeString(accountEscaped, sizeof(accountEscaped), account.c_str(), account.length());
DBManager::instance().Query("INSERT INTO messenger_list%s VALUES ('%s', '%s')",
get_table_postfix(), accountEscaped, companionEscaped);
#else
DBManager::instance().Query("INSERT INTO messenger_list%s VALUES ('%s', '%s')",
get_table_postfix(), account.c_str(), companion.c_str());
#endif
__AddToList(account, companion);
TPacketGGMessenger p2ppck;
p2ppck.bHeader = HEADER_GG_MESSENGER_ADD;
strlcpy(p2ppck.szAccount, account.c_str(), sizeof(p2ppck.szAccount));
strlcpy(p2ppck.szCompanion, companion.c_str(), sizeof(p2ppck.szCompanion));
P2P_MANAGER::instance().Send(&p2ppck, sizeof(TPacketGGMessenger));
}
//MessengerManager::RemoveFromList
void MessengerManager::RemoveFromList(MessengerManager::keyA account, MessengerManager::keyA companion)
{
if (companion.empty())
return;
if (companion.size() == 0)
return;
if (!IsInList(account, companion)) // Fix
return;
char companionEscaped[CHARACTER_NAME_MAX_LEN * 2 + 1];
DBManager::instance().EscapeString(companionEscaped, sizeof(companionEscaped), companion.c_str(), companion.length());
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char accountEscaped[CHARACTER_NAME_MAX_LEN * 2 + 1];
DBManager::instance().EscapeString(accountEscaped, sizeof(accountEscaped), account.c_str(), account.length());
#endif
sys_log(1, "Messenger Remove %s %s", account.c_str(), companion.c_str());
// DBManager::instance().Query("DELETE FROM messenger_list%s WHERE account='%s' AND companion = '%s'",
// get_table_postfix(), account.c_str(), companion.c_str());
// Fix
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
DBManager::instance().Query("DELETE FROM messenger_list%s WHERE account='%s' AND companion = '%s'",
get_table_postfix(), accountEscaped, companionEscaped);
#else
DBManager::instance().Query("DELETE FROM messenger_list%s WHERE account='%s' AND companion = '%s'",
get_table_postfix(), account.c_str(), companionEscaped);
#endif
__RemoveFromList(account, companion);
TPacketGGMessenger p2ppck;
p2ppck.bHeader = HEADER_GG_MESSENGER_REMOVE;
strlcpy(p2ppck.szAccount, account.c_str(), sizeof(p2ppck.szAccount));
strlcpy(p2ppck.szCompanion, companion.c_str(), sizeof(p2ppck.szCompanion));
P2P_MANAGER::instance().Send(&p2ppck, sizeof(TPacketGGMessenger));
}
//MessengerManager::RemoveAllList
void MessengerManager::RemoveAllList(keyA account)
{
std::set<keyT> company(m_Relation[account]);
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapedName[CHARACTER_NAME_MAX_LEN * 2 + 1];
DBManager::instance().EscapeString(escapedName, sizeof(escapedName), account.c_str(), account.length());
DBManager::instance().Query("DELETE FROM messenger_list%s WHERE account='%s' OR companion='%s'",
get_table_postfix(), escapedName, escapedName);
#else
/* SQL Data »èÁ¦ */
DBManager::instance().Query("DELETE FROM messenger_list%s WHERE account='%s' OR companion='%s'",
get_table_postfix(), account.c_str(), account.c_str());
#endif
/* ³»°¡ °¡Áö°íÀÖ´Â ¸®½ºÆ® »èÁ¦ */
for (std::set<keyT>::iterator iter = company.begin();
iter != company.end();
iter++ )
{
this->RemoveFromList(account, *iter);
}
/* º¹»çÇÑ µ¥ÀÌŸ »èÁ¦ */
for (std::set<keyT>::iterator iter = company.begin();
iter != company.end();
)
{
company.erase(iter++);
}
company.clear();
}
Code: game/questlua_pc.cpp
Kod:
//Find in function pc_change_name:
snprintf(szQuery, sizeof(szQuery), "SELECT COUNT(*) FROM player%s WHERE name='%s'", get_table_postfix(), szName);
//Change or replace:
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapedName[CHARACTER_NAME_MAX_LEN * 2 + 1];
size_t nameLen = strnlen(szName, CHARACTER_NAME_MAX_LEN);
DBManager::instance().EscapeString(escapedName, sizeof(escapedName), szName, nameLen);
snprintf(szQuery, sizeof(szQuery), "SELECT COUNT(*) FROM player%s WHERE name='%s'", get_table_postfix(), escapedName);
#else
snprintf(szQuery, sizeof(szQuery), "SELECT COUNT(*) FROM player%s WHERE name='%s'", get_table_postfix(), szName);
#endif
//Find in the same function:
snprintf(szQuery, sizeof(szQuery), "UPDATE player%s SET name='%s' WHERE id=%u", get_table_postfix(), szName, pid);
//Change or replace:
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
snprintf(szQuery, sizeof(szQuery), "UPDATE player%s SET name='%s' WHERE id=%u", get_table_postfix(), escapedName, pid);
#else
snprintf(szQuery, sizeof(szQuery), "UPDATE player%s SET name='%s' WHERE id=%u", get_table_postfix(), szName, pid);
#endif
Code: db/ClientManagerLogin.cpp
Kod:
//Change or replace this function:
void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDChangeName * p)
{
char queryStr[QUERY_MAX_LEN];
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapedName[CHARACTER_NAME_MAX_LEN * 2 + 1];
CDBManager::instance().EscapeString(escapedName, p->name, sizeof(escapedName));
if (g_stLocale == "sjis")
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci AND id <> %u",
GetTablePostfix(), escapedName, p->pid);
else
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' AND id <> %u", GetTablePostfix(), escapedName, p->pid);
#else
if (g_stLocale == "sjis")
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci AND id <> %u",
GetTablePostfix(), p->name, p->pid);
else
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' AND id <> %u", GetTablePostfix(), p->name, p->pid);
#endif
std::unique_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(queryStr, SQL_PLAYER));
if (pMsg->Get()->uiNumRows)
{
if (!pMsg->Get()->pSQLResult)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
if (*row[0] != '0')
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
return;
}
}
else
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
snprintf(queryStr, sizeof(queryStr),
"UPDATE player%s SET name='%s',change_name=0 WHERE id=%u", GetTablePostfix(),escapedName, p->pid);
#else
snprintf(queryStr, sizeof(queryStr),
"UPDATE player%s SET name='%s',change_name=0 WHERE id=%u", GetTablePostfix(), p->name, p->pid);
#endif
std::unique_ptr<SQLMsg> pMsg0(CDBManager::instance().DirectQuery(queryStr, SQL_PLAYER));
TPacketDGChangeName pdg;
peer->EncodeHeader(HEADER_DG_CHANGE_NAME, dwHandle, sizeof(TPacketDGChangeName));
pdg.pid = p->pid;
strlcpy(pdg.name, p->name, sizeof(pdg.name));
peer->Encode(&pdg, sizeof(TPacketDGChangeName));
}
Code: db/ClientManagerPlayer.cpp
Kod:
//Change or replace the function void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerCreatePacket* packet):
void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerCreatePacket* packet)
{
char queryStr[QUERY_MAX_LEN];
int queryLen;
int player_id;
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
char escapedName[CHARACTER_NAME_MAX_LEN * 2 + 1];
size_t nameLen = strnlen(packet->player_table.name, sizeof(packet->player_table.name));
#endif
time_by_id_map_t::iterator it = s_createTimeByAccountID.find(packet->account_id);
if (it != s_createTimeByAccountID.end())
{
time_t curtime = time(0);
if (curtime - it->second < 30)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
}
queryLen = snprintf(queryStr, sizeof(queryStr),
"SELECT pid%u FROM player_index%s WHERE id=%d", packet->account_index + 1, GetTablePostfix(), packet->account_id);
std::unique_ptr<SQLMsg> pMsg0(CDBManager::instance().DirectQuery(queryStr));
if (pMsg0->Get()->uiNumRows != 0)
{
if (!pMsg0->Get()->pSQLResult)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg0->Get()->pSQLResult);
DWORD dwPID = 0; str_to_number(dwPID, row[0]);
if (row[0] && dwPID > 0)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
sys_log(0, "ALREADY EXIST AccountChrIdx %d ID %d", packet->account_index, dwPID);
return;
}
}
else
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
CDBManager::instance().EscapeString(escapedName, packet->player_table.name, nameLen);
if (g_stLocale == "sjis")
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci",
GetTablePostfix(), escapedName);
else
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s'", GetTablePostfix(), escapedName);
std::unique_ptr<SQLMsg> pMsg1(CDBManager::instance().DirectQuery(queryStr));
#else
if (g_stLocale == "sjis")
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci",
GetTablePostfix(), packet->player_table.name);
else
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s'", GetTablePostfix(), packet->player_table.name);
std::unique_ptr<SQLMsg> pMsg1(CDBManager::instance().DirectQuery(queryStr));
#endif
if (pMsg1->Get()->uiNumRows)
{
if (!pMsg1->Get()->pSQLResult)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg1->Get()->pSQLResult);
if (*row[0] != '0')
{
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
sys_log(0, "ALREADY EXIST name %s, row[0] %s query %s", escapedName, row[0], queryStr);
#else
sys_log(0, "ALREADY EXIST name %s, row[0] %s query %s", packet->player_table.name, row[0], queryStr);
#endif
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
return;
}
}
else
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
queryLen = snprintf(queryStr, sizeof(queryStr),
"INSERT INTO player%s "
"(id, account_id, name, level, st, ht, dx, iq, "
"job, voice, dir, x, y, z, "
"hp, mp, random_hp, random_sp, stat_point, stamina, part_base, part_main, part_hair, gold, playtime, "
"skill_level, quickslot) "
"VALUES(0, %u, '%s', %d, %d, %d, %d, %d, "
"%d, %d, %d, %d, %d, %d, %d, "
"%d, %d, %d, %d, %d, %d, %d, 0, %d, 0, ",
GetTablePostfix(),
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
packet->account_id, escapedName, packet->player_table.level, packet->player_table.st, packet->player_table.ht, packet->player_table.dx, packet->player_table.iq,
#else
packet->account_id, packet->player_table.name, packet->player_table.level, packet->player_table.st, packet->player_table.ht, packet->player_table.dx, packet->player_table.iq,
#endif
packet->player_table.job, packet->player_table.voice, packet->player_table.dir, packet->player_table.x, packet->player_table.y, packet->player_table.z,
packet->player_table.hp, packet->player_table.sp, packet->player_table.sRandomHP, packet->player_table.sRandomSP, packet->player_table.stat_point, packet->player_table.stamina, packet->player_table.part_base, packet->player_table.part_base, packet->player_table.gold);
sys_log(0, "PlayerCreate accountid %d name %s level %d gold %d, st %d ht %d job %d",
packet->account_id,
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
escapedName,
#else
packet->player_table.name,
#endif
packet->player_table.level,
packet->player_table.gold,
packet->player_table.st,
packet->player_table.ht,
packet->player_table.job);
static char text[4096 + 1];
CDBManager::instance().EscapeString(text, packet->player_table.skills, sizeof(packet->player_table.skills));
queryLen += snprintf(queryStr + queryLen, sizeof(queryStr) - queryLen, "'%s', ", text);
if (g_test_server)
sys_log(0, "Create_Player queryLen[%d] TEXT[%s]", queryLen, text);
CDBManager::instance().EscapeString(text, packet->player_table.quickslot, sizeof(packet->player_table.quickslot));
queryLen += snprintf(queryStr + queryLen, sizeof(queryStr) - queryLen, "'%s')", text);
std::unique_ptr<SQLMsg> pMsg2(CDBManager::instance().DirectQuery(queryStr));
if (g_test_server)
sys_log(0, "Create_Player queryLen[%d] TEXT[%s]", queryLen, text);
if (pMsg2->Get()->uiAffectedRows <= 0)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
sys_log(0, "ALREADY EXIST3 query: %s AffectedRows %lu", queryStr, pMsg2->Get()->uiAffectedRows);
return;
}
player_id = pMsg2->Get()->uiInsertID;
snprintf(queryStr, sizeof(queryStr), "UPDATE player_index%s SET pid%d=%d WHERE id=%d",
GetTablePostfix(), packet->account_index + 1, player_id, packet->account_id);
std::unique_ptr<SQLMsg> pMsg3(CDBManager::instance().DirectQuery(queryStr));
if (pMsg3->Get()->uiAffectedRows <= 0)
{
sys_err("QUERY_ERROR: %s", queryStr);
snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), player_id);
CDBManager::instance().DirectQuery(queryStr);
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
TPacketDGCreateSuccess pack;
memset(&pack, 0, sizeof(pack));
pack.bAccountCharacterIndex = packet->account_index;
pack.player.dwID = player_id;
#ifdef ENABLE_EXTENDED_PLAYER_NAMES
strlcpy(pack.player.szName, escapedName, sizeof(pack.player.szName));
#else
strlcpy(pack.player.szName, packet->player_table.name, sizeof(pack.player.szName));
#endif
pack.player.byJob = packet->player_table.job;
pack.player.byLevel = 1;
pack.player.dwPlayMinutes = 0;
pack.player.byST = packet->player_table.st;
pack.player.byHT = packet->player_table.ht;
pack.player.byDX = packet->player_table.dx;
pack.player.byIQ = packet->player_table.iq;
pack.player.wMainPart = packet->player_table.part_base;
pack.player.x = packet->player_table.x;
pack.player.y = packet->player_table.y;
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_SUCCESS, dwHandle, sizeof(TPacketDGCreateSuccess));
peer->Encode(&pack, sizeof(TPacketDGCreateSuccess));
sys_log(0, "7 name %s job %d", pack.player.szName, pack.player.byJob);
s_createTimeByAccountID[packet->account_id] = time(0);
}
- Katılım
- 3 Haz 2025
- Konular
- 28
- Mesajlar
- 161
- Çözüm
- 2
- Online süresi
- 6d 6h
- Reaksiyon Skoru
- 91
- Altın Konu
- 0
- TM Yaşı
- 1 Yıl 9 Gün
- Başarım Puanı
- 52
- Yaş
- 29
- MmoLira
- 914
- DevLira
- 39
DB ağlıyor bu şekilde kral isimlerin arasinda boşluk veyada özel karakter kullanımında core + crash yedirir utils.cpp icine özel karakter kullanılmamasi için bir kontrol ekleyip isim ekleme alanına gerekli fonksiyonu cagirman gerekir. Diğer türlü kendini bilmez birisi gelir MySQL fazladan bir veri sıkıştırır veyada packet yollar 1 byte yerine 1000 byte'lik oyun çöker
- Katılım
- 15 May 2013
- Konular
- 1,225
- Mesajlar
- 7,385
- Çözüm
- 6
- Online süresi
- 2mo 16d
- Reaksiyon Skoru
- 6,039
- Altın Konu
- 435
- Başarım Puanı
- 349
- MmoLira
- 3,908
- DevLira
- 6
eline sağlık
- Katılım
- 22 Nis 2024
- Konular
- 35
- Mesajlar
- 301
- Çözüm
- 7
- Online süresi
- 9d 15h
- Reaksiyon Skoru
- 376
- Altın Konu
- 0
- Başarım Puanı
- 97
- MmoLira
- 2,501
- DevLira
- 54
Paylaşım için teşekkürler. Yorum dikkate alınmalı.DB ağlıyor bu şekilde kral isimlerin arasinda boşluk veyada özel karakter kullanımında core + crash yedirir utils.cpp icine özel karakter kullanılmamasi için bir kontrol ekleyip isim ekleme alanına gerekli fonksiyonu cagirman gerekir. Diğer türlü kendini bilmez birisi gelir MySQL fazladan bir veri sıkıştırır veyada packet yollar 1 byte yerine 1000 byte'lik oyun çöker
Şu an konuyu görüntüleyenler (Toplam : 1, Üye: 1, Misafir: 0)
Benzer konular
- Cevaplar
- 24
- Görüntüleme
- 1K
- Cevaplar
- 12
- Görüntüleme
- 1K
- Cevaplar
- 0
- Görüntüleme
- 276
- Cevaplar
- 9
- Görüntüleme
- 449
















