mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 06:50:04 +00:00
fixed potential threading/socket issue
This commit is contained in:
parent
b4fb449e69
commit
062302a7aa
@ -46,31 +46,24 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
|
|||||||
int errorCode = 0;
|
int errorCode = 0;
|
||||||
|
|
||||||
// checking regex
|
// checking regex
|
||||||
if (!CNLoginServer::isLoginDataGood(userLogin, userPassword))
|
if (!CNLoginServer::isLoginDataGood(userLogin, userPassword)) {
|
||||||
{
|
|
||||||
errorCode = (int)LoginError::LOGIN_ERROR;
|
errorCode = (int)LoginError::LOGIN_ERROR;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
std::unique_ptr<Database::Account> findUser = Database::findAccount(userLogin);
|
std::unique_ptr<Database::Account> findUser = Database::findAccount(userLogin);
|
||||||
// if account not found, make new one
|
// if account not found, make new one
|
||||||
if (findUser == nullptr)
|
if (findUser == nullptr) {
|
||||||
{
|
|
||||||
loginSessions[sock] = CNLoginData();
|
loginSessions[sock] = CNLoginData();
|
||||||
loginSessions[sock].userID = Database::addAccount(userLogin, userPassword);
|
loginSessions[sock].userID = Database::addAccount(userLogin, userPassword);
|
||||||
loginSessions[sock].slot = 1;
|
loginSessions[sock].slot = 1;
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
// if user exists, check if password is correct
|
// if user exists, check if password is correct
|
||||||
else if (CNLoginServer::isPasswordCorrect(findUser->Password, userPassword))
|
else if (CNLoginServer::isPasswordCorrect(findUser->Password, userPassword)) {
|
||||||
{
|
|
||||||
/*calling this here to timestamp login attempt,
|
/*calling this here to timestamp login attempt,
|
||||||
* in order to make duplicate exit sanity check work*/
|
* in order to make duplicate exit sanity check work*/
|
||||||
Database::updateSelected(findUser->AccountID, findUser->Selected);
|
Database::updateSelected(findUser->AccountID, findUser->Selected);
|
||||||
// check if account isn't currently in use
|
// check if account isn't currently in use
|
||||||
if (CNLoginServer::isAccountInUse(findUser->AccountID) ||
|
if (CNLoginServer::isAccountInUse(findUser->AccountID)) {
|
||||||
PlayerManager::isAccountInUse(findUser->AccountID))
|
|
||||||
{
|
|
||||||
errorCode = (int)LoginError::ID_ALREADY_IN_USE;
|
errorCode = (int)LoginError::ID_ALREADY_IN_USE;
|
||||||
}
|
}
|
||||||
// if not, login success
|
// if not, login success
|
||||||
@ -82,15 +75,13 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
|
|||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
errorCode = (int)LoginError::ID_AND_PASSWORD_DO_NOT_MATCH;
|
errorCode = (int)LoginError::ID_AND_PASSWORD_DO_NOT_MATCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (success)
|
if (success) {
|
||||||
{
|
|
||||||
std::vector<Player> characters = Database::getCharacters(loginSessions[sock].userID);
|
std::vector<Player> characters = Database::getCharacters(loginSessions[sock].userID);
|
||||||
int charCount = characters.size();
|
int charCount = characters.size();
|
||||||
|
|
||||||
@ -113,8 +104,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
// now send the characters :)
|
// now send the characters :)
|
||||||
std::vector<Player>::iterator it;
|
std::vector<Player>::iterator it;
|
||||||
for (it = characters.begin(); it != characters.end(); it++)
|
for (it = characters.begin(); it != characters.end(); it++) {
|
||||||
{
|
|
||||||
sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO();
|
sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO();
|
||||||
|
|
||||||
charInfo.iSlot = (int8_t)it->slot;
|
charInfo.iSlot = (int8_t)it->slot;
|
||||||
@ -143,9 +133,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
sock->sendPacket((void*)&charInfo, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO));
|
sock->sendPacket((void*)&charInfo, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
// Failure
|
|
||||||
else {
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_LOGIN_FAIL, resp);
|
INITSTRUCT(sP_LS2CL_REP_LOGIN_FAIL, resp);
|
||||||
U8toU16(userLogin, resp.szID);
|
U8toU16(userLogin, resp.szID);
|
||||||
resp.iErrorCode = errorCode;
|
resp.iErrorCode = errorCode;
|
||||||
@ -333,13 +321,16 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
|
|||||||
case P_CL2LS_REQ_CHANGE_CHAR_NAME: {
|
case P_CL2LS_REQ_CHANGE_CHAR_NAME: {
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_CHANGE_CHAR_NAME))
|
if (data->size != sizeof(sP_CL2LS_REQ_CHANGE_CHAR_NAME))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sP_CL2LS_REQ_CHANGE_CHAR_NAME* save = (sP_CL2LS_REQ_CHANGE_CHAR_NAME*)data->buf;
|
sP_CL2LS_REQ_CHANGE_CHAR_NAME* save = (sP_CL2LS_REQ_CHANGE_CHAR_NAME*)data->buf;
|
||||||
Database::changeName(save);
|
Database::changeName(save);
|
||||||
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, resp);
|
INITSTRUCT(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, resp);
|
||||||
resp.iPC_UID = save->iPCUID;
|
resp.iPC_UID = save->iPCUID;
|
||||||
memcpy(resp.szFirstName, save->szFirstName, sizeof(char16_t)*9);
|
memcpy(resp.szFirstName, save->szFirstName, sizeof(char16_t)*9);
|
||||||
memcpy(resp.szLastName, save->szLastName, sizeof(char16_t) * 17);
|
memcpy(resp.szLastName, save->szLastName, sizeof(char16_t) * 17);
|
||||||
resp.iSlotNum = save->iSlotNum;
|
resp.iSlotNum = save->iSlotNum;
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC));
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -349,27 +340,14 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
sP_CL2LS_REQ_PC_EXIT_DUPLICATE* exit = (sP_CL2LS_REQ_PC_EXIT_DUPLICATE*)data->buf;
|
sP_CL2LS_REQ_PC_EXIT_DUPLICATE* exit = (sP_CL2LS_REQ_PC_EXIT_DUPLICATE*)data->buf;
|
||||||
auto account = Database::findAccount(U16toU8(exit->szID));
|
auto account = Database::findAccount(U16toU8(exit->szID));
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (account == nullptr)
|
if (account == nullptr) {
|
||||||
{
|
|
||||||
std::cout << "[WARN] P_CL2LS_REQ_PC_EXIT_DUPLICATE submitted unknown username: " << exit->szID << std::endl;
|
std::cout << "[WARN] P_CL2LS_REQ_PC_EXIT_DUPLICATE submitted unknown username: " << exit->szID << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* sanity check
|
|
||||||
* client is supposed to send us user password for verification,
|
|
||||||
* however it never sends it (>_<)
|
|
||||||
* therefore, we check if the account made a login attempt within last 30s
|
|
||||||
*/
|
|
||||||
if (account->LastLogin + 30000 < getTime())
|
|
||||||
{
|
|
||||||
std::cout << "[WARN] P_CL2LS_REQ_PC_EXIT_DUPLICATE submitted without a login attempt on: " << exit->szID << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int accountId = account->AccountID;
|
|
||||||
if (!exitDuplicate(accountId))
|
|
||||||
PlayerManager::exitDuplicate(accountId);
|
|
||||||
|
|
||||||
|
exitDuplicate(account->AccountID);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -395,8 +373,7 @@ void CNLoginServer::killConnection(CNSocket* cns) {
|
|||||||
#pragma region helperMethods
|
#pragma region helperMethods
|
||||||
bool CNLoginServer::isAccountInUse(int accountId) {
|
bool CNLoginServer::isAccountInUse(int accountId) {
|
||||||
std::map<CNSocket*, CNLoginData>::iterator it;
|
std::map<CNSocket*, CNLoginData>::iterator it;
|
||||||
for (it = CNLoginServer::loginSessions.begin(); it != CNLoginServer::loginSessions.end(); it++)
|
for (it = CNLoginServer::loginSessions.begin(); it != CNLoginServer::loginSessions.end(); it++) {
|
||||||
{
|
|
||||||
if (it->second.userID == accountId)
|
if (it->second.userID == accountId)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -405,10 +382,8 @@ bool CNLoginServer::isAccountInUse(int accountId) {
|
|||||||
|
|
||||||
bool CNLoginServer::exitDuplicate(int accountId) {
|
bool CNLoginServer::exitDuplicate(int accountId) {
|
||||||
std::map<CNSocket*, CNLoginData>::iterator it;
|
std::map<CNSocket*, CNLoginData>::iterator it;
|
||||||
for (it = CNLoginServer::loginSessions.begin(); it != CNLoginServer::loginSessions.end(); it++)
|
for (it = CNLoginServer::loginSessions.begin(); it != CNLoginServer::loginSessions.end(); it++) {
|
||||||
{
|
if (it->second.userID == accountId) {
|
||||||
if (it->second.userID == accountId)
|
|
||||||
{
|
|
||||||
CNSocket* sock = it->first;
|
CNSocket* sock = it->first;
|
||||||
INITSTRUCT(sP_LS2CL_REP_PC_EXIT_DUPLICATE, resp);
|
INITSTRUCT(sP_LS2CL_REP_PC_EXIT_DUPLICATE, resp);
|
||||||
resp.iErrorCode = 0;
|
resp.iErrorCode = 0;
|
||||||
|
@ -227,6 +227,12 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
std::cout << "\tPC_UID: " << plr.PCStyle.iPC_UID << std::endl;
|
std::cout << "\tPC_UID: " << plr.PCStyle.iPC_UID << std::endl;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// check if account is already in use
|
||||||
|
if (isAccountInUse(plr.accountId)) {
|
||||||
|
// kick the other player
|
||||||
|
exitDuplicate(plr.accountId);
|
||||||
|
}
|
||||||
|
|
||||||
response.iID = plr.iID;
|
response.iID = plr.iID;
|
||||||
response.uiSvrTime = getTime();
|
response.uiSvrTime = getTime();
|
||||||
response.PCLoadData2CL.iUserLevel = plr.accountLevel;
|
response.PCLoadData2CL.iUserLevel = plr.accountLevel;
|
||||||
|
Loading…
Reference in New Issue
Block a user