From 2bad1252d3d3811099d3cb28c6089b5c58e5c5d6 Mon Sep 17 00:00:00 2001 From: Kamil Date: Thu, 3 Dec 2020 01:40:36 +0100 Subject: [PATCH] Small DB fixes --- src/BuddyManager.cpp | 17 ++++++----- src/CNLoginServer.cpp | 15 ++++++---- src/Database.cpp | 69 +++++++++++++++++++++++++------------------ src/ItemManager.cpp | 12 ++++---- 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/src/BuddyManager.cpp b/src/BuddyManager.cpp index dc6d9c4..624f447 100644 --- a/src/BuddyManager.cpp +++ b/src/BuddyManager.cpp @@ -64,18 +64,19 @@ void BuddyManager::refreshBuddyList(CNSocket* sock) { int64_t buddyID = plr->buddyIDs[i]; if (buddyID != 0) { sBuddyBaseInfo buddyInfo = {}; - Database::DbPlayer buddyPlayerData = Database::getDbPlayerById(buddyID); - if (buddyPlayerData.PlayerID == -1) + Player buddyPlayerData = {}; + Database::getPlayer(&buddyPlayerData, buddyID); + if (buddyPlayerData.iID == 0) continue; buddyInfo.bBlocked = 0; buddyInfo.bFreeChat = 1; - buddyInfo.iGender = buddyPlayerData.Gender; + buddyInfo.iGender = buddyPlayerData.PCStyle.iGender; buddyInfo.iID = buddyID; buddyInfo.iPCUID = buddyID; - buddyInfo.iNameCheckFlag = buddyPlayerData.NameCheck; - buddyInfo.iPCState = buddyPlayerData.PCState; - U8toU16(buddyPlayerData.FirstName, buddyInfo.szFirstName, sizeof(buddyInfo.szFirstName)); - U8toU16(buddyPlayerData.LastName, buddyInfo.szLastName, sizeof(buddyInfo.szLastName)); + buddyInfo.iNameCheckFlag = buddyPlayerData.PCStyle.iNameCheck; + buddyInfo.iPCState = buddyPlayerData.iPCState; + memcpy(buddyInfo.szFirstName, buddyPlayerData.PCStyle.szFirstName, sizeof(buddyInfo.szFirstName)); + memcpy(buddyInfo.szLastName, buddyPlayerData.PCStyle.szLastName, sizeof(buddyInfo.szLastName)); respdata[buddyIndex] = buddyInfo; buddyIndex++; } @@ -697,7 +698,7 @@ void BuddyManager::emailSend(CNSocket* sock, CNPacketData* data) { U16toU8(plr->PCStyle.szFirstName), // SenderFirstName U16toU8(plr->PCStyle.szLastName), // SenderLastName ChatManager::sanitizeText(U16toU8(pkt->szSubject)), // SubjectLine - ChatManager::sanitizeText(U16toU8(pkt->szContent), true), // MsgBody + ChatManager::sanitizeText(U16toU8(pkt->szContent)), // MsgBody pkt->iCash, // Taros (uint64_t)getTimestamp(), // SendTime 0 // DeleteTime (unimplemented) diff --git a/src/CNLoginServer.cpp b/src/CNLoginServer.cpp index 533dcd0..e2f8b89 100644 --- a/src/CNLoginServer.cpp +++ b/src/CNLoginServer.cpp @@ -326,7 +326,8 @@ void CNLoginServer::characterCreate(CNSocket* sock, CNPacketData* data) { Database::finishCharacter(character); - Player player = Database::getPlayer(character->PCStyle.iPC_UID);; + Player player = {}; + Database::getPlayer(&player, character->PCStyle.iPC_UID); INITSTRUCT(sP_LS2CL_REP_CHAR_CREATE_SUCC, resp); resp.sPC_Style = player.PCStyle; @@ -403,7 +404,8 @@ void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) { resp.g_FE_ServerPort = settings::SHARDPORT; // pass player to CNSharedData - Player passPlayer = Database::getPlayer(selection->iPC_UID); + Player passPlayer = {}; + Database::getPlayer(&passPlayer, selection->iPC_UID); passPlayer.FEKey = sock->getFEKey(); resp.iEnterSerialKey = passPlayer.iID; CNSharedData::setPlayer(resp.iEnterSerialKey, passPlayer); @@ -460,7 +462,7 @@ void CNLoginServer::changeName(CNSocket* sock, CNPacketData* data) { return; } - Database::changeName(save); + Database::changeName(save, loginSessions[sock].userID); INITSTRUCT(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, resp); resp.iPC_UID = save->iPCUID; @@ -485,15 +487,16 @@ void CNLoginServer::duplicateExit(CNSocket* sock, CNPacketData* data) { // TODO: FIX THIS PACKET sP_CL2LS_REQ_PC_EXIT_DUPLICATE* exit = (sP_CL2LS_REQ_PC_EXIT_DUPLICATE*)data->buf; - auto account = Database::findAccount(U16toU8(exit->szID)); + Database::Account account = {}; + Database::findAccount(&account, U16toU8(exit->szID)); // sanity check - if (account == nullptr) { + if (account.AccountID == 0) { std::cout << "[WARN] P_CL2LS_REQ_PC_EXIT_DUPLICATE submitted unknown username: " << exit->szID << std::endl; return; } - exitDuplicate(account->AccountID); + exitDuplicate(account.AccountID); } #pragma endregion diff --git a/src/Database.cpp b/src/Database.cpp index 0e3f9d3..69015c9 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -28,6 +28,8 @@ void Database::open() { terminate(0); } + // foreign keys are off by default + sqlite3_exec(db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL); createTables(); std::cout << "[INFO] Database in operation "; @@ -228,7 +230,8 @@ int Database::addAccount(std::string login, std::string password) { sqlite3_prepare_v2(db, sql, -1, &stmt, 0); sqlite3_bind_text(stmt, 1, login.c_str(), -1, 0); - sqlite3_bind_text(stmt, 2, BCrypt::generateHash(password).c_str(), -1, 0); + std::string hashedPassword = BCrypt::generateHash(password); + sqlite3_bind_text(stmt, 2, hashedPassword.c_str(), -1, 0); int rc = sqlite3_step(stmt); sqlite3_finalize(stmt); @@ -446,7 +449,7 @@ bool Database::finishCharacter(sP_CL2LS_REQ_CHAR_CREATE* character) { sqlite3_prepare_v2(db, sql, -1, &stmt, 0); sqlite3_bind_int(stmt, 1, character->PCStyle.iPC_UID); - int rc = sqlite3_step(stmt); + rc = sqlite3_step(stmt); sqlite3_finalize(stmt); if (rc != SQLITE_DONE) @@ -774,7 +777,7 @@ void Database::getPlayer(Player* plr, int id) { p.XCoordinates, p.YCoordinates, p.ZCoordinates, p.NameCheck, p.Angle, p.HP, p.AccountLevel, p.FusionMatter, p.Taros, p.Quests, p.BatteryW, p.BatteryN, p.Mentor, p.WarpLocationFlag, - p.SkywayLocationFlag1, p.SkywayLocationFlag2, p.CurrentMissionID + p.SkywayLocationFlag1, p.SkywayLocationFlag2, p.CurrentMissionID, a.Body, a.EyeColor, a.FaceStyle, a.Gender, a.HairColor, a.HairStyle, a.Height, a.SkinColor FROM "Players" as p INNER JOIN "Appearances" as a ON p.PlayerID = a.PlayerID @@ -795,10 +798,10 @@ void Database::getPlayer(Player* plr, int id) { plr->accountId = sqlite3_column_int(stmt, 0); plr->slot = sqlite3_column_int(stmt, 1); - + // parsing const unsigned char* to char16_t std::string placeHolder = std::string(reinterpret_cast(sqlite3_column_text(stmt, 2))); - U8toU16(placeHolder, plr->PCStyle.szFirstName , sizeof(plr->PCStyle.szFirstName)); + U8toU16(placeHolder, plr->PCStyle.szFirstName, sizeof(plr->PCStyle.szFirstName)); placeHolder = std::string(reinterpret_cast(sqlite3_column_text(stmt, 3))); U8toU16(placeHolder, plr->PCStyle.szLastName, sizeof(plr->PCStyle.szLastName)); @@ -822,16 +825,15 @@ void Database::getPlayer(Player* plr, int id) { plr->fusionmatter = sqlite3_column_int(stmt, 18); plr->money = sqlite3_column_int(stmt, 19); - const void* questBuffer = plr->aQuestFlag; - questBuffer = sqlite3_column_blob(stmt, 20); - + memcpy(plr->aQuestFlag, sqlite3_column_blob(stmt, 20), sizeof(plr->aQuestFlag)); + plr->batteryW = sqlite3_column_int(stmt, 21); plr->batteryN = sqlite3_column_int(stmt, 22); plr->mentor = sqlite3_column_int(stmt, 23); plr->iWarpLocationFlag = sqlite3_column_int(stmt, 24); - plr->aSkywayLocationFlag[0] = sqlite3_column_int(stmt, 25); - plr->aSkywayLocationFlag[1] = sqlite3_column_int(stmt, 26); + plr->aSkywayLocationFlag[0] = sqlite3_column_int64(stmt, 25); + plr->aSkywayLocationFlag[1] = sqlite3_column_int64(stmt, 26); plr->CurrentMissionID = sqlite3_column_int(stmt, 27); plr->PCStyle.iBody = sqlite3_column_int(stmt, 28); @@ -976,8 +978,8 @@ void Database::updatePlayer(Player *player) { sqlite3_bind_int(stmt, 13, player->batteryW); sqlite3_bind_int(stmt, 14, player->batteryN); sqlite3_bind_int(stmt, 15, player->iWarpLocationFlag); - sqlite3_bind_int(stmt, 16, player->aSkywayLocationFlag[0]); - sqlite3_bind_int(stmt, 17, player->aSkywayLocationFlag[1]); + sqlite3_bind_int64(stmt, 16, player->aSkywayLocationFlag[0]); + sqlite3_bind_int64(stmt, 17, player->aSkywayLocationFlag[1]); sqlite3_bind_int(stmt, 18, player->CurrentMissionID); sqlite3_bind_int(stmt, 19, player->iID); @@ -998,20 +1000,22 @@ void Database::updatePlayer(Player *player) { sql = R"( INSERT INTO "Inventory" - ("PlayerID", "Slot", "Type", "Opt" "Id", "Timelimit") + ("PlayerID", "Slot", "Type", "Opt" , "Id", "Timelimit") VALUES (?, ?, ?, ?, ?, ?); )"; sqlite3_prepare_v2(db, sql, -1, &stmt, 0); - int i = -1; - while (++i < AEQUIP_COUNT && player->Equip[i].iID != 0) { + for (int i = 0; i < AEQUIP_COUNT; i++) { + if (player->Equip[i].iID == 0) + continue; + sqlite3_bind_int(stmt, 1, player->iID); sqlite3_bind_int(stmt, 2, i); sqlite3_bind_int(stmt, 3, player->Equip[i].iType); sqlite3_bind_int(stmt, 4, player->Equip[i].iOpt); sqlite3_bind_int(stmt, 5, player->Equip[i].iID); sqlite3_bind_int(stmt, 6, player->Equip[i].iTimeLimit); - + if (sqlite3_step(stmt) != SQLITE_DONE) { sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); sqlite3_finalize(stmt); @@ -1021,8 +1025,10 @@ void Database::updatePlayer(Player *player) { sqlite3_reset(stmt); } - i = -1; - while (++i < AINVEN_COUNT && player->Inven[i].iID != 0) { + for (int i = 0; i < AINVEN_COUNT; i++) { + if (player->Inven[i].iID == 0) + continue; + sqlite3_bind_int(stmt, 1, player->iID); sqlite3_bind_int(stmt, 2, i + AEQUIP_COUNT); sqlite3_bind_int(stmt, 3, player->Inven[i].iType); @@ -1049,13 +1055,15 @@ void Database::updatePlayer(Player *player) { sql = R"( INSERT INTO "QuestItems" - ("PlayerID", "Slot", "Opt" "Id") + ("PlayerID", "Slot", "Opt", "Id") VALUES (?, ?, ?, ?); )"; sqlite3_prepare_v2(db, sql, -1, &stmt, 0); - i = -1; - while (++i < AQINVEN_COUNT && player->QInven[i].iID != 0) { + for (int i = 0; i < AQINVEN_COUNT; i++) { + if (player->QInven[i].iID == 0) + continue; + sqlite3_bind_int(stmt, 1, player->iID); sqlite3_bind_int(stmt, 2, i); sqlite3_bind_int(stmt, 3, player->QInven[i].iOpt); @@ -1080,13 +1088,15 @@ void Database::updatePlayer(Player *player) { sql = R"( INSERT INTO "Nanos" - ("PlayerID", "Id", "SKill" "Stamina") + ("PlayerID", "Id", "SKill", "Stamina") VALUES (?, ?, ?, ?); )"; sqlite3_prepare_v2(db, sql, -1, &stmt, 0); - i = -1; - while (++i < SIZEOF_NANO_BANK_SLOT && player->Nanos[i].iID != 0) { + for (int i = 0; i < SIZEOF_NANO_BANK_SLOT; i++) { + if (player->Nanos[i].iID == 0) + continue; + sqlite3_bind_int(stmt, 1, player->iID); sqlite3_bind_int(stmt, 2, player->Nanos[i].iID); sqlite3_bind_int(stmt, 3, player->Nanos[i].iSkillID); @@ -1116,8 +1126,9 @@ void Database::updatePlayer(Player *player) { )"; sqlite3_prepare_v2(db, sql, -1, &stmt, 0); - i = -1; - while (++i < ACTIVE_MISSION_COUNT && player->tasks[i] != 0) { + for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) { + if (player->tasks[i] == 0) + continue; sqlite3_bind_int(stmt, 1, player->iID); sqlite3_bind_int(stmt, 2, player->tasks[i]); sqlite3_bind_int(stmt, 3, player->RemainingNPCCount[i][0]); @@ -1394,7 +1405,7 @@ void Database::updateEmailContent(EmailData* data) { // TODO: CHANGE THIS TO UPDATE sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL); - const char* sql = R"( + sql = R"( DELETE FROM "EmailData" WHERE "PlayerId" = ? AND "MsgIndex" = ?; )"; @@ -1403,10 +1414,10 @@ void Database::updateEmailContent(EmailData* data) { sqlite3_bind_int(stmt, 2, data->MsgIndex); sqlite3_step(stmt); - const char* sql = R"( + sql = R"( INSERT INTO "EmailData" ("PlayerId", "MsgIndex", "ReadFlag", "ItemFlag", "SenderId", "SenderFirstName", "SenderLastName", - "SubjectLine", "MsgBody", "Taros", "SendTime", "DeleteTime" + "SubjectLine", "MsgBody", "Taros", "SendTime", "DeleteTime" ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); )"; sqlite3_prepare_v2(db, sql, -1, &stmt, 0); diff --git a/src/ItemManager.cpp b/src/ItemManager.cpp index 994f9ea..c97f134 100644 --- a/src/ItemManager.cpp +++ b/src/ItemManager.cpp @@ -74,9 +74,9 @@ void ItemManager::itemMoveHandler(CNSocket* sock, CNPacketData* data) { case SlotType::INVENTORY: fromItem = &plr->Inven[itemmove->iFromSlotNum]; break; - case SlotType::BANK: + /*case SlotType::BANK: fromItem = &plr->Bank[itemmove->iFromSlotNum]; - break; + break;*/ default: std::cout << "[WARN] MoveItem submitted unknown Item Type?! " << itemmove->eFrom << std::endl; return; @@ -91,9 +91,9 @@ void ItemManager::itemMoveHandler(CNSocket* sock, CNPacketData* data) { case SlotType::INVENTORY: toItem = &plr->Inven[itemmove->iToSlotNum]; break; - case SlotType::BANK: - toItem = &plr->Bank[itemmove->iToSlotNum]; - break; + //case SlotType::BANK: + // toItem = &plr->Bank[itemmove->iToSlotNum]; + // break; default: std::cout << "[WARN] MoveItem submitted unknown Item Type?! " << itemmove->eTo << std::endl; return; @@ -320,7 +320,7 @@ void ItemManager::itemBankOpenHandler(CNSocket* sock, CNPacketData* data) { // just send bank inventory INITSTRUCT(sP_FE2CL_REP_PC_BANK_OPEN_SUCC, resp); for (int i = 0; i < ABANK_COUNT; i++) { - resp.aBank[i] = plr->Bank[i]; + //resp.aBank[i] = plr->Bank[i]; } resp.iExtraBank = 1; sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_BANK_OPEN_SUCC, sizeof(sP_FE2CL_REP_PC_BANK_OPEN_SUCC));