added a sanity check for entering invalid characters

This commit is contained in:
Kamil 2020-11-17 03:21:41 +01:00 committed by Gent S
parent 4760d91ccd
commit 5c6d7d6055
3 changed files with 34 additions and 9 deletions

View File

@ -255,7 +255,7 @@ void CNLoginServer::nameSave(CNSocket* sock, CNPacketData* data) {
std::cout << "\tName: " << U16toU8(save->szFirstName) << " " << U16toU8(save->szLastName) << std::endl; std::cout << "\tName: " << U16toU8(save->szFirstName) << " " << U16toU8(save->szLastName) << std::endl;
) )
resp.iSlotNum = save->iSlotNum; resp.iSlotNum = save->iSlotNum;
resp.iGender = save->iGender; resp.iGender = save->iGender;
resp.iPC_UID = Database::createCharacter(save, loginSessions[sock].userID); resp.iPC_UID = Database::createCharacter(save, loginSessions[sock].userID);
memcpy(resp.szFirstName, save->szFirstName, sizeof(char16_t) * 9); memcpy(resp.szFirstName, save->szFirstName, sizeof(char16_t) * 9);
@ -273,6 +273,15 @@ void CNLoginServer::characterCreate(CNSocket* sock, CNPacketData* data) {
return; return;
sP_CL2LS_REQ_CHAR_CREATE* character = (sP_CL2LS_REQ_CHAR_CREATE*)data->buf; sP_CL2LS_REQ_CHAR_CREATE* character = (sP_CL2LS_REQ_CHAR_CREATE*)data->buf;
if (!(Database::validateCharacter(character->PCStyle.iPC_UID, loginSessions[sock].userID) ||
loginSessions[sock].characters.find(character->PCStyle.iPC_UID) == loginSessions[sock].characters.end())) {
INITSTRUCT(sP_LS2CL_REP_SHARD_SELECT_FAIL, fail);
fail.iErrorCode = 2;
sock->sendPacket((void*)&fail, P_LS2CL_REP_SHARD_SELECT_FAIL, sizeof(sP_LS2CL_REP_SHARD_SELECT_FAIL));
return;
}
Database::finishCharacter(character); Database::finishCharacter(character);
DEBUGLOG( DEBUGLOG(
@ -294,7 +303,7 @@ void CNLoginServer::characterCreate(CNSocket* sock, CNPacketData* data) {
std::cout << "\tiEquipFootID: " << (int)character->sOn_Item.iEquipFootID << std::endl; std::cout << "\tiEquipFootID: " << (int)character->sOn_Item.iEquipFootID << std::endl;
) )
Player player = Database::getPlayer(character->PCStyle.iPC_UID); Player player = Database::getPlayer(character->PCStyle.iPC_UID);
int64_t UID = player.iID; int64_t UID = player.iID;
INITSTRUCT(sP_LS2CL_REP_CHAR_CREATE_SUCC, resp); INITSTRUCT(sP_LS2CL_REP_CHAR_CREATE_SUCC, resp);
@ -324,6 +333,7 @@ void CNLoginServer::characterDelete(CNSocket* sock, CNPacketData* data) {
resp.iSlotNum = operationResult; resp.iSlotNum = operationResult;
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_SUCC, sizeof(sP_LS2CL_REP_CHAR_DELETE_SUCC)); sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_SUCC, sizeof(sP_LS2CL_REP_CHAR_DELETE_SUCC));
loginSessions[sock].lastHeartbeat = getTime(); loginSessions[sock].lastHeartbeat = getTime();
loginSessions[sock].characters.erase(del->iPC_UID);
} }
void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) { void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) {
@ -331,18 +341,26 @@ void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) {
return; return;
// character selected // character selected
sP_CL2LS_REQ_CHAR_SELECT* chararacter = (sP_CL2LS_REQ_CHAR_SELECT*)data->buf; sP_CL2LS_REQ_CHAR_SELECT* character = (sP_CL2LS_REQ_CHAR_SELECT*)data->buf;
INITSTRUCT(sP_LS2CL_REP_CHAR_SELECT_SUCC, resp); INITSTRUCT(sP_LS2CL_REP_CHAR_SELECT_SUCC, resp);
if (!(Database::validateCharacter(character->iPC_UID, loginSessions[sock].userID) ||
loginSessions[sock].characters.find(character->iPC_UID) == loginSessions[sock].characters.end())) {
INITSTRUCT(sP_LS2CL_REP_SHARD_SELECT_FAIL, fail);
fail.iErrorCode = 2;
sock->sendPacket((void*)&fail, P_LS2CL_REP_SHARD_SELECT_FAIL, sizeof(sP_LS2CL_REP_SHARD_SELECT_FAIL));
return;
}
DEBUGLOG( DEBUGLOG(
std::cout << "P_CL2LS_REQ_CHAR_SELECT:" << std::endl; std::cout << "P_CL2LS_REQ_CHAR_SELECT:" << std::endl;
std::cout << "\tPC_UID: " << chararacter->iPC_UID << std::endl; std::cout << "\tPC_UID: " << character->iPC_UID << std::endl;
) )
loginSessions[sock].lastHeartbeat = getTime(); loginSessions[sock].lastHeartbeat = getTime();
loginSessions[sock].selectedChar = chararacter->iPC_UID; loginSessions[sock].selectedChar = character->iPC_UID;
Database::updateSelected(loginSessions[sock].userID, loginSessions[sock].characters[chararacter->iPC_UID].slot); Database::updateSelected(loginSessions[sock].userID, loginSessions[sock].characters[character->iPC_UID].slot);
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_SELECT_SUCC, sizeof(sP_LS2CL_REP_CHAR_SELECT_SUCC)); sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_SELECT_SUCC, sizeof(sP_LS2CL_REP_CHAR_SELECT_SUCC));
} }

View File

@ -191,6 +191,12 @@ std::unique_ptr<Database::Account> Database::findAccount(std::string login) {
std::unique_ptr<Account>(new Account(find.front())); std::unique_ptr<Account>(new Account(find.front()));
} }
bool Database::validateCharacter(int characterID, int userID) {
return db.select(&DbPlayer::PlayerID,
where((c(&DbPlayer::PlayerID) == characterID) && (c(&DbPlayer::AccountID) == userID)))
.size() > 0;
}
bool Database::isNameFree(sP_CL2LS_REQ_CHECK_CHAR_NAME* nameCheck) { bool Database::isNameFree(sP_CL2LS_REQ_CHECK_CHAR_NAME* nameCheck) {
std::lock_guard<std::mutex> lock(dbCrit); std::lock_guard<std::mutex> lock(dbCrit);

View File

@ -119,6 +119,7 @@ namespace Database {
int addAccount(std::string login, std::string password); int addAccount(std::string login, std::string password);
void updateSelected(int accountId, int playerId); void updateSelected(int accountId, int playerId);
std::unique_ptr<Account> findAccount(std::string login); std::unique_ptr<Account> findAccount(std::string login);
bool validateCharacter(int characterID, int userID);
bool isNameFree(sP_CL2LS_REQ_CHECK_CHAR_NAME* nameCheck); bool isNameFree(sP_CL2LS_REQ_CHECK_CHAR_NAME* nameCheck);
// called after chosing name, returns ID // called after chosing name, returns ID
int createCharacter(sP_CL2LS_REQ_SAVE_CHAR_NAME* save, int AccountID); int createCharacter(sP_CL2LS_REQ_SAVE_CHAR_NAME* save, int AccountID);